From 2121f18a246fda7987461a302ecb2a3b1024ac3f Mon Sep 17 00:00:00 2001
From: TinchoF <50110327+TinchoF@users.noreply.github.com>
Date: Tue, 8 Oct 2019 10:00:07 -0300
Subject: [PATCH 01/38] Outcon bid adapter. (#4161)
* Outcon bid adapter.
* Fix identation
* Fixes
* Fixes
* Fixes
* Spec fixes
* Fixes
* Fix urls
* Fix
* Fix parameters
* Fix space operators
* Fix bidder timeout
* Update
* Fix whitespace
* no message
* Outcon unit test
* no message
* no message
* no message
* no message
* Fixes
* Fixes
* Change url
* no message
* no message
* no message
* Added bidId
* no message
* no message
* no message
* no message
* Wrapping url with html
* no message
* no message
* no message
---
modules/outconAdapter.md | 26 ++++++
modules/outconBidAdapter.js | 59 +++++++++++++
test/spec/modules/outconBidAdapter_spec.js | 98 ++++++++++++++++++++++
3 files changed, 183 insertions(+)
create mode 100644 modules/outconAdapter.md
create mode 100644 modules/outconBidAdapter.js
create mode 100644 test/spec/modules/outconBidAdapter_spec.js
diff --git a/modules/outconAdapter.md b/modules/outconAdapter.md
new file mode 100644
index 00000000000..88ed45396bc
--- /dev/null
+++ b/modules/outconAdapter.md
@@ -0,0 +1,26 @@
+# 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
new file mode 100644
index 00000000000..d691e807059
--- /dev/null
+++ b/modules/outconBidAdapter.js
@@ -0,0 +1,59 @@
+import {registerBidder} from '../src/adapters/bidderFactory';
+import {config} from '../src/config';
+
+const BIDDER_CODE = 'outcon';
+export const spec = {
+ code: BIDDER_CODE,
+ 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 par = '';
+ let url = '';
+ 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;
+ switch (validBidRequests[i].params.env) {
+ case 'test':
+ par = par + '&demo=true';
+ url = 'http://test.outcondigital.com:8048/ad/' + par;
+ break;
+ case 'api':
+ url = 'http://api.outcondigital.com:8048/ad/' + par;
+ break;
+ case 'stg':
+ url = 'http://stg.outcondigital.com:8048/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: config.getConfig('_bidderTimeout'),
+ ad: wrapDisplayUrl(serverResponse.body.creatives[0].url, serverResponse.body.type),
+ vastImpUrl: serverResponse.body.trackingURL
+ };
+ bidResponses.push(bidResponse);
+ return bidResponses;
+ },
+}
+
+function wrapDisplayUrl(displayUrl, type) {
+ if (type == 'video') return `
`;
+ if (type == 'banner') return `
`;
+}
+
+registerBidder(spec);
diff --git a/test/spec/modules/outconBidAdapter_spec.js b/test/spec/modules/outconBidAdapter_spec.js
new file mode 100644
index 00000000000..dc9c96ed3a3
--- /dev/null
+++ b/test/spec/modules/outconBidAdapter_spec.js
@@ -0,0 +1,98 @@
+import { expect } from 'chai';
+import { spec } from '../../../modules/outconBidAdapter';
+
+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: 'http://test.outcondigital.com:8048/ad/',
+ data: {
+ pod: '5d603538eba7192ae14e39a4',
+ env: 'test'
+ }
+ };
+ const bidResponse = {
+ body: {
+ cpm: 0.10,
+ cur: 'USD',
+ exp: 10,
+ creatives: [
+ {
+ url: 'http://test.outcondigital.com/uploads/5d42e7a7306ea4689b67c122/frutas.mp4',
+ size: 3,
+ width: 1920,
+ height: 1080,
+ codec: 'video/mp4'
+ }
+ ],
+ id: '5d6e6aef22063e392bf7f564',
+ type: 'video',
+ campaign: '5d42e44b306ea469593c76a2',
+ trackingURL: 'http://test.outcondigital.com:8048/ad/track?track=5d6e6aef22063e392bf7f564'
+ },
+ };
+ 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'
+ ];
+ let resultKeys = Object.keys(result[0]);
+ resultKeys.forEach(function(key) {
+ expect(requiredKeys.indexOf(key) !== -1).to.equal(true);
+ });
+ })
+ });
+});
From 3ee0d9795afcaff341ec322d662df183a1f564b9 Mon Sep 17 00:00:00 2001
From: Jaimin Panchal <7393273+jaiminpanchal27@users.noreply.github.com>
Date: Tue, 8 Oct 2019 14:49:11 -0400
Subject: [PATCH 02/38] Adding workflow to run end to end tests (#4230)
* Adding workflow to run end to end tests
* trying self branch
* Update to run at 12 every day
* cleanup config using aliases
* update branch and cron time
* add command
---
.circleci/config.yml | 133 ++++++++++++++++++++++++++++---------------
1 file changed, 86 insertions(+), 47 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 73ec23aa740..0d48ec13fa1 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -2,54 +2,93 @@
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
+
+aliases:
+ - &environment
+ docker:
+ # specify the version you desire here
+ - image: circleci/node:8.9.0
+
+ # 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:
- docker:
- # specify the version you desire here
- - image: circleci/node:8.9.0
+ <<: *environment
+ steps: *unit_test_steps
- # 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
-
- steps:
- - checkout
-
- # Download and cache dependencies
- - restore_cache:
- keys:
- - v1-dependencies-{{ checksum "package.json" }}
- # fallback to using the latest cache if no exact match is found
- - v1-dependencies-
-
- - run: npm install
-
- - save_cache:
- paths:
- - node_modules
- key: v1-dependencies-{{ checksum "package.json" }}
-
- - run: sudo npm install -g gulp-cli
-
- # Download and run BrowserStack local
- - run:
- 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} &
- # run tests!
- - run:
- name: BrowserStack testing
- command: gulp test --browserstack --nolintfix
- # run e2e tests
- - run:
- name: Functional testing
- command: echo "127.0.0.1 test.localhost" | sudo tee -a /etc/hosts && gulp e2e-test --host=test.localhost --file=./test/spec/e2e/banner/basic_banner_ad.spec.js
+ e2etest:
+ <<: *environment
+ steps: *endtoend_test_steps
+
+workflows:
+ version: 2
+ commit:
+ jobs:
+ - build
+ nightly:
+ triggers:
+ - schedule:
+ cron: "0 0 * * *"
+ filters:
+ branches:
+ only:
+ - master
+ jobs:
+ - e2etest
From 6af3e5fc8a4775b188ce4f587bb5cf450ab99dda Mon Sep 17 00:00:00 2001
From: Jaimin Panchal <7393273+jaiminpanchal27@users.noreply.github.com>
Date: Tue, 8 Oct 2019 15:29:02 -0400
Subject: [PATCH 03/38] update prebid path for e2e test pages (#4274)
---
integrationExamples/longform/basic_w_bidderSettings.html | 2 +-
integrationExamples/longform/basic_w_priceGran.html | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/integrationExamples/longform/basic_w_bidderSettings.html b/integrationExamples/longform/basic_w_bidderSettings.html
index 4ccb01fbd6e..f9389686b1f 100644
--- a/integrationExamples/longform/basic_w_bidderSettings.html
+++ b/integrationExamples/longform/basic_w_bidderSettings.html
@@ -5,7 +5,7 @@
Prebid Freewheel Integration Demo
-
+
-->
-
+
+ data-player-host="${urls.vlHost}">
Date: Tue, 15 Oct 2019 19:49:51 +0200
Subject: [PATCH 24/38] [Orbidder-Adapter] Add bidRequestCount and remove
bid.params.keyValues (#4264)
* initial orbidder version in personal github repo
* use adUnits from orbidder_example.html
* replace obsolete functions
* forgot to commit the test
* check if bidderRequest object is available
* try to fix weird safari/ie issue
* ebayK: add more params
* update orbidderBidAdapter.md
* use spec.
instead of this. for consistency reasons
* add bidfloor parameter to params object
* fix gdpr object handling
* default to consentRequired: false when not explicitly given
* wip - use onSetTargeting callback
* add tests for onSetTargeting callback
* fix params and respective tests
* remove not used bid.params.keyValues
* add bidRequestCount to orbidder.otto.de/bid Post request
* add bidRequestCount to test object defaultBidRequest
---
modules/orbidderBidAdapter.js | 2 +-
test/spec/modules/orbidderBidAdapter_spec.js | 13 +------------
2 files changed, 2 insertions(+), 13 deletions(-)
diff --git a/modules/orbidderBidAdapter.js b/modules/orbidderBidAdapter.js
index 954ad82261f..88534ae1596 100644
--- a/modules/orbidderBidAdapter.js
+++ b/modules/orbidderBidAdapter.js
@@ -19,7 +19,6 @@ export const spec = {
(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.keyValues === 'undefined') || (typeof bid.params.keyValues === 'object')) &&
((typeof bid.params.profile === 'undefined') || (typeof bid.params.profile === 'object')));
},
@@ -38,6 +37,7 @@ export const spec = {
auctionId: bidRequest.auctionId,
transactionId: bidRequest.transactionId,
adUnitCode: bidRequest.adUnitCode,
+ bidRequestCount: bidRequest.bidRequestCount,
sizes: bidRequest.sizes,
params: bidRequest.params
}
diff --git a/test/spec/modules/orbidderBidAdapter_spec.js b/test/spec/modules/orbidderBidAdapter_spec.js
index aeaa5f30446..1b76de9841a 100644
--- a/test/spec/modules/orbidderBidAdapter_spec.js
+++ b/test/spec/modules/orbidderBidAdapter_spec.js
@@ -10,6 +10,7 @@ describe('orbidderBidAdapter', () => {
bidId: 'd66fa86787e0b0ca900a96eacfd5f0bb',
auctionId: 'ccc4c7cdfe11cfbd74065e6dd28413d8',
transactionId: 'd58851660c0c4461e4aa06344fc9c0c6',
+ bidRequestCount: 1,
adUnitCode: 'adunit-code',
sizes: [[300, 250], [300, 600]],
params: {
@@ -46,12 +47,6 @@ describe('orbidderBidAdapter', () => {
expect(spec.isBidRequestValid(defaultBidRequest)).to.equal(true);
});
- it('accepts optional keyValues object', () => {
- const bidRequest = deepClone(defaultBidRequest);
- bidRequest.params.keyValues = {'key': 'value'};
- expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- });
-
it('accepts optional profile object', () => {
const bidRequest = deepClone(defaultBidRequest);
bidRequest.params.profile = {'key': 'value'};
@@ -64,12 +59,6 @@ describe('orbidderBidAdapter', () => {
expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
});
- it('doesn\'t accept malformed keyValues', () => {
- const bidRequest = deepClone(defaultBidRequest);
- bidRequest.params.keyValues = 'another not usable 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';
From 6fb670620346c34c19b819661c1b59938cb06e41 Mon Sep 17 00:00:00 2001
From: Anand Venkatraman
Date: Tue, 15 Oct 2019 23:23:37 +0530
Subject: [PATCH 25/38] PulsePoint: remove usage of deprecated utils method /
prep for 3.0 (#4257)
* ET-1691: Pulsepoint Analytics adapter for Prebid. (#1)
* ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter
* ET-1691: Adding pulsepoint analytics and tests for pulsepoint adapter
* ET-1691: cleanup
* ET-1691: minor
* ET-1691: revert package.json change
* Adding bidRequest to bidFactory.createBid method as per https://github.com/prebid/Prebid.js/issues/509
* ET-1765: Adding support for additional params in PulsePoint adapter (#2)
* ET-1850: Fixing https://github.com/prebid/Prebid.js/issues/866
* Minor fix
* Adding mandatory parameters to Bid
* Removing usage of deprecated utils method
* minor refactor
---
modules/pulsepointBidAdapter.js | 12 +++---
.../spec/modules/pulsepointBidAdapter_spec.js | 42 +++++++++++--------
2 files changed, 30 insertions(+), 24 deletions(-)
diff --git a/modules/pulsepointBidAdapter.js b/modules/pulsepointBidAdapter.js
index 9c0d67d9612..fee247ba31f 100644
--- a/modules/pulsepointBidAdapter.js
+++ b/modules/pulsepointBidAdapter.js
@@ -40,7 +40,7 @@ export const spec = {
const request = {
id: bidRequests[0].bidderRequestId,
imp: bidRequests.map(slot => impression(slot)),
- site: site(bidRequests),
+ site: site(bidRequests, bidderRequest),
app: app(bidRequests),
device: device(),
bcat: bidRequests[0].params.bcat,
@@ -100,7 +100,7 @@ function bidResponseAvailable(request, response) {
idToBidMap[bid.impid] = bid;
}));
}
- if (request.bidderRequest) {
+ if (request.bidderRequest && request.bidderRequest.bids) {
request.bidderRequest.bids.forEach(bid => {
idToSlotConfig[bid.bidId] = bid;
});
@@ -307,16 +307,16 @@ function dataAsset(id, params, type, defaultLen) {
/**
* Produces an OpenRTB site object.
*/
-function site(bidderRequest) {
- const pubId = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.cp : '0';
- const appParams = bidderRequest[0].params.app;
+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: utils.getTopWindowLocation().href,
+ page: bidderRequest && bidderRequest.refererInfo ? bidderRequest.refererInfo.referer : '',
}
}
return null;
diff --git a/test/spec/modules/pulsepointBidAdapter_spec.js b/test/spec/modules/pulsepointBidAdapter_spec.js
index 1d22ca6eadc..9ed6d3631f5 100644
--- a/test/spec/modules/pulsepointBidAdapter_spec.js
+++ b/test/spec/modules/pulsepointBidAdapter_spec.js
@@ -1,7 +1,7 @@
/* eslint dot-notation:0, quote-props:0 */
import {expect} from 'chai';
import {spec} from 'modules/pulsepointBidAdapter';
-import {deepClone, getTopWindowLocation} from 'src/utils';
+import {deepClone} from 'src/utils';
describe('PulsePoint Adapter Tests', function () {
const slotConfigs = [{
@@ -138,9 +138,14 @@ describe('PulsePoint Adapter Tests', function () {
}
}
}];
+ const bidderRequest = {
+ refererInfo: {
+ referer: 'https://publisher.com/home'
+ }
+ };
it('Verify build request', function () {
- const request = spec.buildRequests(slotConfigs);
+ 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;
@@ -149,7 +154,7 @@ describe('PulsePoint Adapter Tests', function () {
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(getTopWindowLocation().href);
+ 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);
@@ -167,7 +172,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify parse response', function () {
- const request = spec.buildRequests(slotConfigs);
+ const request = spec.buildRequests(slotConfigs, bidderRequest);
const ortbRequest = request.data;
const ortbResponse = {
seatbid: [{
@@ -196,7 +201,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify use ttl in ext', function () {
- const request = spec.buildRequests(slotConfigs);
+ const request = spec.buildRequests(slotConfigs, bidderRequest);
const ortbRequest = request.data;
const ortbResponse = {
seatbid: [{
@@ -222,13 +227,13 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify full passback', function () {
- const request = spec.buildRequests(slotConfigs);
+ 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);
+ 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;
@@ -266,7 +271,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify Native response', function () {
- const request = spec.buildRequests(nativeSlotConfig);
+ 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;
@@ -355,7 +360,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify app requests', function () {
- const request = spec.buildRequests(appSlotConfig);
+ const request = spec.buildRequests(appSlotConfig, bidderRequest);
const ortbRequest = request.data;
// site object
expect(ortbRequest.site).to.equal(null);
@@ -368,13 +373,13 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify GDPR', function () {
- const bidderRequest = {
+ const bidderRequestGdpr = {
gdprConsent: {
gdprApplies: true,
consentString: 'serialized_gpdr_data'
}
};
- const request = spec.buildRequests(slotConfigs, bidderRequest);
+ 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;
@@ -389,7 +394,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify Video request', function () {
- const request = spec.buildRequests(videoSlotConfig);
+ 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;
@@ -409,7 +414,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify Video response', function () {
- const request = spec.buildRequests(videoSlotConfig);
+ 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;
@@ -433,7 +438,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify extra parameters', function () {
- let request = spec.buildRequests(additionalParamsConfig);
+ let request = spec.buildRequests(additionalParamsConfig, bidderRequest);
let ortbRequest = request.data;
expect(ortbRequest).to.not.equal(null);
expect(ortbRequest.imp).to.have.lengthOf(1);
@@ -448,7 +453,7 @@ describe('PulsePoint Adapter Tests', function () {
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);
+ request = spec.buildRequests(outstreamSlotConfig, bidderRequest);
ortbRequest = request.data;
expect(ortbRequest).to.not.equal(null);
expect(ortbRequest.imp).to.have.lengthOf(1);
@@ -456,7 +461,7 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify ortb parameters', function () {
- const request = spec.buildRequests(ortbParamsSlotConfig);
+ 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']);
@@ -472,7 +477,8 @@ describe('PulsePoint Adapter Tests', function () {
});
it('Verify outstream renderer', function () {
- const request = spec.buildRequests(outstreamSlotConfig, {bids: [outstreamSlotConfig[0]]});
+ 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;
@@ -521,7 +527,7 @@ describe('PulsePoint Adapter Tests', function () {
}
}
};
- const request = spec.buildRequests(bidRequests);
+ const request = spec.buildRequests(bidRequests, bidderRequest);
expect(request).to.be.not.null;
const ortbRequest = request.data;
expect(request.data).to.be.not.null;
From d549a409db808f16a40b68f85d3dafdeeca4b32a Mon Sep 17 00:00:00 2001
From: Jaimin Panchal <7393273+jaiminpanchal27@users.noreply.github.com>
Date: Tue, 15 Oct 2019 13:59:18 -0400
Subject: [PATCH 26/38] Use isArray method (#4288)
---
src/adapters/bidderFactory.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js
index 90cab154fd4..4ccbfd89457 100644
--- a/src/adapters/bidderFactory.js
+++ b/src/adapters/bidderFactory.js
@@ -9,7 +9,7 @@ import CONSTANTS from '../constants.json';
import events from '../events';
import includes from 'core-js/library/fn/array/includes';
import { ajax } from '../ajax';
-import { logWarn, logError, parseQueryStringParameters, delayExecution, parseSizesInput, getBidderRequest, flatten, uniques, timestamp, setDataInLocalStorage, getDataFromLocalStorage, deepAccess } from '../utils';
+import { logWarn, logError, parseQueryStringParameters, delayExecution, parseSizesInput, getBidderRequest, flatten, uniques, timestamp, setDataInLocalStorage, getDataFromLocalStorage, deepAccess, isArray } from '../utils';
import { ADPOD } from '../mediaTypes';
import { getHook } from '../hook';
@@ -290,7 +290,7 @@ export function newBidder(spec) {
}
if (bids) {
- if (bids.forEach) {
+ if (isArray(bids)) {
bids.forEach(addBidUsingRequestMap);
} else {
addBidUsingRequestMap(bids);
From fceb471e7d1e61698e6e8c6141d551c01ed7a3db Mon Sep 17 00:00:00 2001
From: Eyas Ranjous
Date: Tue, 15 Oct 2019 15:03:09 -0500
Subject: [PATCH 27/38] Add Parrable ID submodule (#4266)
* add parrable id submodule
* fix integration test config
* fix var name
* always refresh sotredId for parrable
* add submodulesThatAlwaysRefresh concept
* remove comment
* add parrable url as one string
* add parrable prod endpoint
* use .indexOf instead of .includes
* add params to test config
* comment failing test
* uncomment failing assertion
* add parrable ID to prebid server adapter
* add parrableIdSystem to .submodules.json
* extract parrableId unit tests from userId spec
* remove breakline between imports
* remove unused param
* remove userId generic feature from parrableId module
* remove trailing space
* fix failing test due to none merged conflict
---
integrationExamples/gpt/userId_example.html | 11 +++
modules/.submodules.json | 1 +
modules/parrableIdSystem.js | 92 +++++++++++++++++++
modules/prebidServerBidAdapter/index.js | 11 ++-
modules/userId/index.js | 1 +
modules/userId/userId.md | 11 +++
test/spec/modules/parrableIdSystem_spec.js | 77 ++++++++++++++++
.../modules/prebidServerBidAdapter_spec.js | 3 +
8 files changed, 206 insertions(+), 1 deletion(-)
create mode 100644 modules/parrableIdSystem.js
create mode 100644 test/spec/modules/parrableIdSystem_spec.js
diff --git a/integrationExamples/gpt/userId_example.html b/integrationExamples/gpt/userId_example.html
index 09e9e4147fc..6d2c2ce677a 100644
--- a/integrationExamples/gpt/userId_example.html
+++ b/integrationExamples/gpt/userId_example.html
@@ -152,6 +152,17 @@
refreshInSeconds: 8*3600 // Refresh frequency of cookies, defaulting to 'expires'
},
+ }, {
+ name: "parrableId",
+ params: {
+ // change to Parrable Partner Client ID(s) you received from the Parrable Partners you are using
+ partner: '30182847-e426-4ff9-b2b5-9ca1324ea09b'
+ },
+ storage: {
+ type: "cookie",
+ name: "_parrable_eid", // create a cookie with this name
+ expires: 365 // cookie can last for a year
+ }
}, {
name: "pubCommonId",
storage: {
diff --git a/modules/.submodules.json b/modules/.submodules.json
index 81c82603083..09063deea40 100644
--- a/modules/.submodules.json
+++ b/modules/.submodules.json
@@ -3,6 +3,7 @@
"digiTrustIdSystem",
"id5IdSystem",
"criteortusIdSystem",
+ "parrableIdSystem",
"liveIntentIdSystem"
],
"adpod": [
diff --git a/modules/parrableIdSystem.js b/modules/parrableIdSystem.js
new file mode 100644
index 00000000000..e8ad7f9acc1
--- /dev/null
+++ b/modules/parrableIdSystem.js
@@ -0,0 +1,92 @@
+/**
+ * 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'
+import {ajax} from '../src/ajax';
+import {submodule} from '../src/hook';
+
+const PARRABLE_URL = 'https://h.parrable.com/prebid';
+
+function isValidConfig(configParams) {
+ if (!configParams) {
+ utils.logError('User ID - parrableId submodule requires configParams');
+ return false;
+ }
+ if (!configParams.partner) {
+ utils.logError('User ID - parrableId submodule requires partner list');
+ return false;
+ }
+ return true;
+}
+
+function fetchId(configParams, consentData, currentStoredId) {
+ if (!isValidConfig(configParams)) return;
+
+ const data = {
+ eid: currentStoredId || null,
+ trackers: configParams.partner.split(',')
+ };
+
+ const searchParams = {
+ data: btoa(JSON.stringify(data)),
+ _rand: Math.random()
+ };
+
+ const options = {
+ method: 'GET',
+ withCredentials: true
+ };
+
+ const callback = function (cb) {
+ const onSuccess = (response) => {
+ let eid;
+ if (response) {
+ try {
+ let responseObj = JSON.parse(response);
+ eid = responseObj ? responseObj.eid : undefined;
+ } catch (error) {
+ utils.logError(error);
+ }
+ }
+ cb(eid);
+ };
+ ajax(PARRABLE_URL, onSuccess, searchParams, options);
+ };
+
+ return { callback };
+};
+
+/** @type {Submodule} */
+export const parrableIdSubmodule = {
+ /**
+ * used to link submodule with config
+ * @type {string}
+ */
+ name: 'parrableId',
+ /**
+ * decode the stored id value for passing to bid requests
+ * @function
+ * @param {Object|string} value
+ * @return {(Object|undefined}
+ */
+ decode(value) {
+ return (value && typeof value === 'string') ? { 'parrableid': value } : undefined;
+ },
+
+ /**
+ * performs action to obtain id and return a value in the callback's response argument
+ * @function
+ * @param {SubmoduleParams} [configParams]
+ * @param {ConsentData} [consentData]
+ * @returns {function(callback:function)}
+ */
+ getId(configParams, consentData, currentStoredId) {
+ return fetchId(configParams, consentData, currentStoredId);
+ }
+};
+
+submodule('userId', parrableIdSubmodule);
diff --git a/modules/prebidServerBidAdapter/index.js b/modules/prebidServerBidAdapter/index.js
index 7776db714dd..872e0bb81d9 100644
--- a/modules/prebidServerBidAdapter/index.js
+++ b/modules/prebidServerBidAdapter/index.js
@@ -698,7 +698,7 @@ const OPEN_RTB_PROTOCOL = {
}
const bidUserId = utils.deepAccess(bidRequests, '0.bids.0.userId');
- if (bidUserId && typeof bidUserId === 'object' && (bidUserId.tdid || bidUserId.pubcid || bidUserId.lipb)) {
+ if (bidUserId && typeof bidUserId === 'object' && (bidUserId.tdid || bidUserId.pubcid || bidUserId.parrableid || bidUserId.lipb)) {
utils.deepSetValue(request, 'user.ext.eids', []);
if (bidUserId.tdid) {
@@ -722,6 +722,15 @@ const OPEN_RTB_PROTOCOL = {
});
}
+ if (bidUserId.parrableid) {
+ request.user.ext.eids.push({
+ source: 'parrable.com',
+ uids: [{
+ id: bidUserId.parrableid
+ }]
+ });
+ }
+
if (bidUserId.lipb && bidUserId.lipb.lipbid) {
request.user.ext.eids.push({
source: 'liveintent.com',
diff --git a/modules/userId/index.js b/modules/userId/index.js
index baeb1e2574c..ac96fd2cec8 100644
--- a/modules/userId/index.js
+++ b/modules/userId/index.js
@@ -371,6 +371,7 @@ function initSubmodules(submodules, consentData) {
utils.logWarn(`${MODULE_NAME} - gdpr permission not valid for local storage or cookies, exit module`);
return [];
}
+
return submodules.reduce((carry, submodule) => {
// 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
diff --git a/modules/userId/userId.md b/modules/userId/userId.md
index b5b8c216ead..9b363bbcf64 100644
--- a/modules/userId/userId.md
+++ b/modules/userId/userId.md
@@ -32,6 +32,17 @@ pbjs.setConfig({
name: "id5id",
expires: 5, // Expiration of cookies in days
refreshInSeconds: 8*3600 // User Id cache lifetime in seconds, defaulting to 'expires'
+ },
+ }, {
+ name: 'parrableId',
+ params: {
+ // Replace the list contents with the Parrable Partner Client IDs for Parrable-aware bid adapters in use
+ partners: [ "30182847-e426-4ff9-b2b5-9ca1324ea09b" ]
+ },
+ storage: {
+ type: 'cookie',
+ name: '_parrable_eid',
+ expires: 365
}
}, {
name: 'identityLink',
diff --git a/test/spec/modules/parrableIdSystem_spec.js b/test/spec/modules/parrableIdSystem_spec.js
new file mode 100644
index 00000000000..540e63aa630
--- /dev/null
+++ b/test/spec/modules/parrableIdSystem_spec.js
@@ -0,0 +1,77 @@
+import { expect } from 'chai';
+import {config} from 'src/config';
+import * as utils from 'src/utils';
+import { init, requestBidsHook, setSubmoduleRegistry } from 'modules/userId/index.js';
+import { parrableIdSubmodule } from 'modules/parrableIdSystem';
+
+const EXPIRED_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:01 GMT';
+const P_COOKIE_NAME = '_parrable_eid';
+const P_COOKIE_VALUE = '01.1563917337.test-eid';
+const P_CONFIG_MOCK = {
+ name: 'parrableId',
+ params: {
+ partner: 'parrable_test_partner_123,parrable_test_partner_456'
+ },
+ storage: {
+ name: '_parrable_eid',
+ type: 'cookie',
+ expires: 364
+ }
+};
+
+describe('Parrable ID System', function() {
+ 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' }
+ }]
+ };
+ }
+
+ describe('Parrable ID in Bid Request', function() {
+ let adUnits;
+
+ beforeEach(function() {
+ adUnits = [getAdUnitMock()];
+ });
+
+ it('should append parrableid to bid request', function(done) {
+ // simulate existing browser local storage values
+ utils.setCookie(
+ P_COOKIE_NAME,
+ P_COOKIE_VALUE,
+ (new Date(Date.now() + 5000).toUTCString())
+ );
+
+ setSubmoduleRegistry([parrableIdSubmodule]);
+ init(config);
+ config.setConfig(getConfigMock());
+
+ requestBidsHook(function() {
+ adUnits.forEach(unit => {
+ unit.bids.forEach(bid => {
+ expect(bid).to.have.deep.nested.property('userId.parrableid');
+ expect(bid.userId.parrableid).to.equal(P_COOKIE_VALUE);
+ });
+ });
+ utils.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE);
+ done();
+ }, { adUnits });
+ });
+ });
+});
diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js
index 1c10130a84e..658f130d144 100644
--- a/test/spec/modules/prebidServerBidAdapter_spec.js
+++ b/test/spec/modules/prebidServerBidAdapter_spec.js
@@ -1044,6 +1044,7 @@ describe('S2S Adapter', function () {
userIdBidRequest[0].bids[0].userId = {
tdid: 'abc123',
pubcid: '1234',
+ parrableid: '01.1563917337.test-eid',
lipb: {
lipbid: 'li-xyz'
}
@@ -1057,6 +1058,8 @@ describe('S2S Adapter', function () {
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 === 'pubcommon')).is.not.empty;
expect(requestBid.user.ext.eids.filter(eid => eid.source === 'pubcommon')[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');
});
From 29520f396781647a377d60b34b3d9effac465102 Mon Sep 17 00:00:00 2001
From: Bret Gorsline
Date: Tue, 15 Oct 2019 16:58:50 -0400
Subject: [PATCH 28/38] Prebid 2.36.0 Release
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index ca06ddb8b24..fbbf5ef66d3 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "prebid.js",
- "version": "2.36.0-pre",
+ "version": "2.36.0",
"description": "Header Bidding Management Library",
"main": "src/prebid.js",
"scripts": {
From f498ba8fbbf95bc0d26183a160dcf72fcaec1351 Mon Sep 17 00:00:00 2001
From: Bret Gorsline
Date: Tue, 15 Oct 2019 17:11:39 -0400
Subject: [PATCH 29/38] Increment pre version
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index fbbf5ef66d3..0200db4eace 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "prebid.js",
- "version": "2.36.0",
+ "version": "2.37.0-pre",
"description": "Header Bidding Management Library",
"main": "src/prebid.js",
"scripts": {
From b363e97ed3e4aa2f3799a54d832c7b341392d863 Mon Sep 17 00:00:00 2001
From: Michael
Date: Tue, 15 Oct 2019 15:20:11 -0700
Subject: [PATCH 30/38] Support schain module and send bidfloor param in
Sharethrough adapter (#4271)
* Add support for supply chain object module
Story: [#168742394](https://www.pivotaltracker.com/story/show/168742394)
Co-authored-by: Josh Becker
* Add bidfloor parameter to bid request sent to STX
Story: [#168742573](https://www.pivotaltracker.com/story/show/168742573)
---
modules/sharethroughBidAdapter.js | 8 ++++
.../modules/sharethroughBidAdapter_spec.js | 38 +++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/modules/sharethroughBidAdapter.js b/modules/sharethroughBidAdapter.js
index 7fe41b2b7ae..117088f5355 100644
--- a/modules/sharethroughBidAdapter.js
+++ b/modules/sharethroughBidAdapter.js
@@ -41,6 +41,14 @@ export const sharethroughAdapterSpec = {
query.ttduid = bidRequest.userId.tdid;
}
+ if (bidRequest.schain) {
+ query.schain = JSON.stringify(bidRequest.schain);
+ }
+
+ if (bidRequest.bidfloor) {
+ query.bidfloor = parseFloat(bidRequest.bidfloor);
+ }
+
// Data that does not need to go to the server,
// but we need as part of interpretResponse()
const strData = {
diff --git a/test/spec/modules/sharethroughBidAdapter_spec.js b/test/spec/modules/sharethroughBidAdapter_spec.js
index afa5f44959c..8a8ccdbbeb3 100644
--- a/test/spec/modules/sharethroughBidAdapter_spec.js
+++ b/test/spec/modules/sharethroughBidAdapter_spec.js
@@ -280,6 +280,44 @@ describe('sharethrough adapter spec', function () {
}
});
});
+
+ 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 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('.interpretResponse', function () {
From 493bd5e0d7d97b00b3908c3e47372e8f69410817 Mon Sep 17 00:00:00 2001
From: hbanalytics <55453525+hbanalytics@users.noreply.github.com>
Date: Wed, 16 Oct 2019 01:30:50 +0300
Subject: [PATCH 31/38] Platform One Analytics Adapter (#4233)
* Added Y1 Analytics Adapter
* rename y1AnalyticsAdapter in yieldoneAnalyticsAdapter
* Yieldone Bid Adapter: fixes from lint check
* Yieldone Analytics Adapter: fix endpoint protocol
* Added spec file for yieldone Analytics Adapter
---
modules/yieldoneAnalyticsAdapter.js | 122 +++++++++
modules/yieldoneAnalyticsAdapter.md | 21 ++
.../modules/yieldoneAnalyticsAdapter_spec.js | 256 ++++++++++++++++++
3 files changed, 399 insertions(+)
create mode 100644 modules/yieldoneAnalyticsAdapter.js
create mode 100644 modules/yieldoneAnalyticsAdapter.md
create mode 100644 test/spec/modules/yieldoneAnalyticsAdapter_spec.js
diff --git a/modules/yieldoneAnalyticsAdapter.js b/modules/yieldoneAnalyticsAdapter.js
new file mode 100644
index 00000000000..94dd0daa0b2
--- /dev/null
+++ b/modules/yieldoneAnalyticsAdapter.js
@@ -0,0 +1,122 @@
+import {ajax} from '../src/ajax';
+import adapter from '../src/AnalyticsAdapter';
+import CONSTANTS from '../src/constants.json';
+import adapterManager from '../src/adapterManager';
+import { targeting } from '../src/targeting';
+import { auctionManager } from '../src/auctionManager';
+import * as utils from '../src/utils';
+
+const ANALYTICS_CODE = 'yieldone';
+const analyticsType = 'endpoint';
+// const VERSION = '1.0.0';
+const defaultUrl = '//pool.tsukiji.iponweb.net/hba';
+const requestedBidders = {};
+const requestedBids = {};
+const referrers = {};
+
+let currentAuctionId = '';
+let url = defaultUrl;
+let pubId = '';
+
+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] = [];
+ if (requestedBidders[reqBidderId] && requestedBids[reqBidId]) {
+ if (!reqBidders[bid.bidder]) {
+ reqBidders[bid.bidder] = requestedBidders[reqBidderId];
+ reqBidders[bid.bidder].pubId = pubId;
+ eventsStorage[bid.auctionId].push({eventType, params: reqBidders[bid.bidder]});
+ delete requestedBidders[reqBidderId];
+ }
+ reqBidders[bid.bidder].bids.push(requestedBids[reqBidId]);
+ delete requestedBids[reqBidId];
+ }
+ });
+ } else {
+ args.pubId = pubId;
+ currentAuctionId = args.auctionId || currentAuctionId;
+ if (currentAuctionId) {
+ const eventsStorage = yieldoneAnalytics.eventsStorage;
+ if (!eventsStorage[currentAuctionId]) eventsStorage[currentAuctionId] = [];
+ const referrer = args.refererInfo && args.refererInfo.referer;
+ if (referrer && referrers[currentAuctionId] !== referrer) {
+ referrers[currentAuctionId] = referrer;
+ }
+ eventsStorage[currentAuctionId].push({
+ eventType,
+ params: args
+ });
+ }
+ }
+ if (
+ eventType === CONSTANTS.EVENTS.AUCTION_END || eventType === CONSTANTS.EVENTS.BID_WON
+ ) {
+ args.adServerTargeting = targeting.getAllTargeting(
+ auctionManager.getAdUnitCodes(),
+ auctionManager.getBidsReceived()
+ );
+ if (yieldoneAnalytics.eventsStorage[args.auctionId]) {
+ yieldoneAnalytics.eventsStorage[args.auctionId].forEach((it) => {
+ it.page = {url: referrers[currentAuctionId]};
+ });
+ }
+ yieldoneAnalytics.sendStat(yieldoneAnalytics.eventsStorage[args.auctionId], args.auctionId);
+ }
+ },
+ sendStat(events, auctionId) {
+ if (!events) return;
+ delete yieldoneAnalytics.eventsStorage[auctionId];
+ ajax(
+ url,
+ {
+ success: function() {},
+ error: function() {}
+ },
+ JSON.stringify(events),
+ {
+ 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
new file mode 100644
index 00000000000..43be87b114b
--- /dev/null
+++ b/modules/yieldoneAnalyticsAdapter.md
@@ -0,0 +1,21 @@
+# 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/test/spec/modules/yieldoneAnalyticsAdapter_spec.js b/test/spec/modules/yieldoneAnalyticsAdapter_spec.js
new file mode 100644
index 00000000000..a297403b2e0
--- /dev/null
+++ b/test/spec/modules/yieldoneAnalyticsAdapter_spec.js
@@ -0,0 +1,256 @@
+import yieldoneAnalytics from 'modules/yieldoneAnalyticsAdapter';
+import { targeting } from 'src/targeting';
+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]]
+ }
+ ]
+ }
+ ];
+
+ const responses = [
+ {
+ width: 300,
+ height: 250,
+ statusMessage: 'Bid available',
+ bidId: '1234',
+ auctionId: auctionId,
+ cpm: 0.1,
+ bidder: 'biddertest_1',
+ adUnitCode: '0000',
+ timeToRespond: 100
+ },
+ {
+ width: 336,
+ height: 280,
+ statusMessage: 'Bid available',
+ bidId: '5678',
+ auctionId: auctionId,
+ cpm: 0.2,
+ bidder: 'biddertest_1',
+ adUnitCode: '0000',
+ timeToRespond: 100
+ },
+ {
+ 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'
+ }
+ ];
+
+ const winner = {
+ width: 300,
+ height: 250,
+ statusMessage: 'Bid available',
+ bidId: '91011',
+ auctionId: auctionId,
+ cpm: 0.3,
+ bidder: 'biddertest_2',
+ adUnitCode: '0000',
+ timeToRespond: 100
+ };
+
+ const expectedEvents = [
+ {
+ eventType: constants.EVENTS.AUCTION_INIT,
+ page: {url: testReferrer},
+ params: {
+ config: initOptions,
+ auctionId: auctionId,
+ pubId: initOptions.pubId
+ }
+ },
+ {
+ eventType: constants.EVENTS.BID_REQUESTED,
+ page: {url: testReferrer},
+ params: Object.assign({pubId: initOptions.pubId}, request[0])
+ },
+ {
+ eventType: constants.EVENTS.BID_REQUESTED,
+ page: {url: testReferrer},
+ params: Object.assign({pubId: initOptions.pubId}, request[1])
+ },
+ {
+ eventType: constants.EVENTS.BID_REQUESTED,
+ page: {url: testReferrer},
+ params: Object.assign({pubId: initOptions.pubId}, request[2])
+ },
+ {
+ eventType: constants.EVENTS.BID_RESPONSE,
+ page: {url: testReferrer},
+ params: Object.assign({pubId: initOptions.pubId}, responses[0])
+ },
+ {
+ eventType: constants.EVENTS.BID_RESPONSE,
+ page: {url: testReferrer},
+ params: Object.assign({pubId: initOptions.pubId}, responses[1])
+ },
+ {
+ eventType: constants.EVENTS.BID_RESPONSE,
+ page: {url: testReferrer},
+ params: Object.assign({pubId: initOptions.pubId}, responses[2])
+ },
+ {
+ eventType: constants.EVENTS.BID_TIMEOUT,
+ page: {url: testReferrer},
+ params: Object.assign({pubId: initOptions.pubId}, request[2])
+ },
+ {
+ eventType: constants.EVENTS.AUCTION_END,
+ page: {url: testReferrer},
+ params: {
+ auctionId: auctionId,
+ pubId: initOptions.pubId,
+ adServerTargeting: fakeTargeting
+ }
+ }
+ ];
+
+ const wonExpectedEvents = [
+ {
+ eventType: constants.EVENTS.BID_WON,
+ page: {url: testReferrer},
+ params: Object.assign({pubId: initOptions.pubId, adServerTargeting: fakeTargeting}, winner)
+ }
+ ];
+
+ 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]]);
+
+ events.emit(constants.EVENTS.AUCTION_END, {auctionId: auctionId});
+
+ expect(yieldoneAnalytics.eventsStorage[auctionId]).to.deep.equal(expectedEvents);
+
+ 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(wonExpectedEvents);
+
+ delete yieldoneAnalytics.eventsStorage[auctionId];
+ done();
+ }, 1000);
+ });
+ });
+});
From 44192a8cdd0a92aac852c46bfe6ef0b9248be518 Mon Sep 17 00:00:00 2001
From: Eyas Ranjous
Date: Wed, 16 Oct 2019 09:07:40 -0500
Subject: [PATCH 32/38] Fix parrable id integration example (#4317)
* fix parrableId integration example
* add parentheses
---
modules/userId/userId.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/userId/userId.md b/modules/userId/userId.md
index 9b363bbcf64..b10aa2adc20 100644
--- a/modules/userId/userId.md
+++ b/modules/userId/userId.md
@@ -36,8 +36,8 @@ pbjs.setConfig({
}, {
name: 'parrableId',
params: {
- // Replace the list contents with the Parrable Partner Client IDs for Parrable-aware bid adapters in use
- partners: [ "30182847-e426-4ff9-b2b5-9ca1324ea09b" ]
+ // 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"
},
storage: {
type: 'cookie',
From cb3c457b0d3c1bbbb397d7d21dd6a9658036a946 Mon Sep 17 00:00:00 2001
From: Jozef Bartek <31618107+jbartek25@users.noreply.github.com>
Date: Wed, 16 Oct 2019 17:55:43 +0200
Subject: [PATCH 33/38] Improve Digital adapter: support for video (#4318)
* Bid floor, https, native ad update
* Update the ad server protocol module
* Adding referrer
* Improve Digital support for video
* Improve Digital adapter: video
* adapter version -> 6.0.0
---
modules/improvedigitalBidAdapter.js | 14 +++-
.../modules/improvedigitalBidAdapter_spec.js | 82 +++++++++++++++++++
2 files changed, 93 insertions(+), 3 deletions(-)
diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js
index 61074985597..4ee2226395b 100644
--- a/modules/improvedigitalBidAdapter.js
+++ b/modules/improvedigitalBidAdapter.js
@@ -1,15 +1,15 @@
import * as utils from '../src/utils';
import { registerBidder } from '../src/adapters/bidderFactory';
import { config } from '../src/config';
-import { BANNER, NATIVE } from '../src/mediaTypes';
+import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes';
const BIDDER_CODE = 'improvedigital';
export const spec = {
- version: '5.3.0',
+ version: '6.0.0',
code: BIDDER_CODE,
aliases: ['id'],
- supportedMediaTypes: [BANNER, NATIVE],
+ supportedMediaTypes: [BANNER, NATIVE, VIDEO],
/**
* Determines whether or not the given bid request is valid.
@@ -87,6 +87,9 @@ export const spec = {
bid.native.impressionTrackers.unshift(bidObject.nurl);
}
bid.mediaType = NATIVE;
+ } else if (bidObject.ad_type && bidObject.ad_type === 'video') {
+ bid.vastXml = bidObject.adm;
+ bid.mediaType = VIDEO;
} else {
// Banner
let nurl = '';
@@ -186,6 +189,11 @@ function getNormalizedBidRequest(bid) {
const bidFloorCur = utils.getBidIdParameter('bidFloorCur', bid.params);
let normalizedBidRequest = {};
+ const videoMediaType = utils.deepAccess(bid, 'mediaTypes.video');
+ const context = utils.deepAccess(bid, 'mediaTypes.video.context');
+ if (bid.mediaType === 'video' || (videoMediaType && context !== 'outstream')) {
+ normalizedBidRequest.adTypes = [ VIDEO ];
+ }
if (placementId) {
normalizedBidRequest.placementId = placementId;
} else {
diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js
index 2bff6fba5bc..2d9d51c0d68 100644
--- a/test/spec/modules/improvedigitalBidAdapter_spec.js
+++ b/test/spec/modules/improvedigitalBidAdapter_spec.js
@@ -193,6 +193,38 @@ describe('Improve Digital Adapter Tests', function () {
expect(params.bid_request.referrer).to.equal('https://blah.com/test.html');
});
+ it('should add ad type for instream video', function () {
+ let bidRequest = Object.assign({}, simpleBidRequest);
+ bidRequest.mediaType = 'video';
+ let request = spec.buildRequests([bidRequest])[0];
+ let params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length)));
+ expect(params.bid_request.imp[0].ad_types).to.deep.equal(['video']);
+
+ bidRequest = Object.assign({}, simpleBidRequest);
+ bidRequest.mediaTypes = {
+ video: {
+ context: 'instream',
+ playerSize: [640, 480]
+ }
+ };
+ request = spec.buildRequests([bidRequest])[0];
+ params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length)));
+ expect(params.bid_request.imp[0].ad_types).to.deep.equal(['video']);
+ });
+
+ it('should not set ad type for outstream video', function() {
+ const bidRequest = Object.assign({}, simpleBidRequest);
+ bidRequest.mediaTypes = {
+ video: {
+ context: 'outstream',
+ playerSize: [640, 480]
+ }
+ };
+ const request = spec.buildRequests([bidRequest])[0];
+ const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length)));
+ expect(params.bid_request.imp[0].ad_types).to.not.exist;
+ });
+
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);
@@ -456,6 +488,34 @@ describe('Improve Digital Adapter Tests', function () {
}
};
+ 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,
@@ -552,6 +612,22 @@ describe('Improve Digital Adapter Tests', function () {
}
];
+ let expectedBidVideo = [
+ {
+ 'vastXml': '',
+ 'adId': '33e9500b21129f',
+ 'creativeId': '422031',
+ 'cpm': 1.45888594164456,
+ 'currency': 'USD',
+ 'height': 290,
+ 'mediaType': 'video',
+ 'netRevenue': false,
+ 'requestId': '33e9500b21129f',
+ 'ttl': 300,
+ 'width': 600
+ }
+ ];
+
it('should return a well-formed bid', function () {
const bids = spec.interpretResponse(serverResponse);
expect(bids).to.deep.equal(expectedBid);
@@ -667,6 +743,12 @@ describe('Improve Digital Adapter Tests', function () {
delete bids[0].ortbNative;
expect(bids).to.deep.equal(expectedBids);
});
+
+ // Video
+ it('should return a well-formed video bid', function () {
+ const bids = spec.interpretResponse(serverResponseVideo);
+ expect(bids).to.deep.equal(expectedBidVideo);
+ });
});
describe('getUserSyncs', function () {
From fd865b1626ceebdaa5d6b4e346515c92317bc497 Mon Sep 17 00:00:00 2001
From: Salomon Rada
Date: Wed, 16 Oct 2019 19:04:57 +0300
Subject: [PATCH 34/38] Gamoshi: Update aliases list. Add support for userSync.
(#4319)
* Add support for multi-format ad units. Add favoredMediaType property to params.
* Add tests for gdpr consent.
* Add adId to outbids
* Modify media type resolving
* Refactor multi-format ad units handler.
* Modify the way of sending GDPR data.
Update aliases.
* Add new consent fields. Add unit test.
* Add new consent fields. Add unit test.
* Add support for id5 and unified id cookie sync.
* Add support for id5 and unified id cookie sync.
* Add restricted check for gdpr consent.
---
modules/gamoshiBidAdapter.js | 58 ++++++++++++++++-----
test/spec/modules/gamoshiBidAdapter_spec.js | 38 +++++++++++++-
2 files changed, 81 insertions(+), 15 deletions(-)
diff --git a/modules/gamoshiBidAdapter.js b/modules/gamoshiBidAdapter.js
index ec146b77c70..b18188cf33a 100644
--- a/modules/gamoshiBidAdapter.js
+++ b/modules/gamoshiBidAdapter.js
@@ -42,17 +42,16 @@ export const helper = {
export const spec = {
code: 'gamoshi',
- aliases: ['gambid', 'cleanmedia', 'viewdeos', '9MediaOnline'],
+ aliases: ['gambid', 'cleanmedia', '9MediaOnline'],
supportedMediaTypes: ['banner', 'video'],
isBidRequestValid: function (bid) {
- return !!bid.params.supplyPartnerId &&
- typeof bid.params.supplyPartnerId === 'string' &&
- (typeof bid.params['rtbEndpoint'] === 'undefined' || typeof bid.params['rtbEndpoint'] === '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);
+ return !!bid.params.supplyPartnerId && utils.isStr(bid.params.supplyPartnerId) &&
+ (!bid.params['rtbEndpoint'] || utils.isStr(bid.params['rtbEndpoint'])) &&
+ (!bid.params.bidfloor || utils.isNumber(bid.params.bidfloor)) &&
+ (!bid.params['adpos'] || utils.isNumber(bid.params['adpos'])) &&
+ (!bid.params['protocols'] || Array.isArray(bid.params['protocols'])) &&
+ (!bid.params.instl || bid.params.instl === 0 || bid.params.instl === 1);
},
buildRequests: function (validBidRequests, bidderRequest) {
@@ -75,16 +74,24 @@ export const spec = {
'imp': [],
'ext': {}
};
+ const gdprConsent = bidderRequest.gdprConsent;
- if (bidderRequest.gdprConsent &&
- bidderRequest.gdprConsent.consentString &&
- bidderRequest.gdprConsent.gdprApplies) {
+ if (gdprConsent && gdprConsent.consentString && gdprConsent.gdprApplies) {
rtbBidRequest.ext.gdpr_consent = {
- consent_string: bidderRequest.gdprConsent.consentString,
- consent_required: bidderRequest.gdprConsent.gdprApplies
+ consent_string: gdprConsent.consentString,
+ consent_required: gdprConsent.gdprApplies
};
+ rtbBidRequest.regs = {
+ ext: {
+ gdpr: gdprConsent.gdprApplies === true ? 1 : 0
+ }
+ };
+ rtbBidRequest.user = {
+ ext: {
+ consent: gdprConsent.consentString
+ }
+ }
}
-
const imp = {
'id': transactionId,
'instl': params.instl === 1 ? 1 : 0,
@@ -129,6 +136,15 @@ export const spec = {
}
}
+ let eids = [];
+ if (bidRequest && bidRequest.userId) {
+ addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.id5id`), 'id5-sync.com', 'ID5ID');
+ addExternalUserId(eids, utils.deepAccess(bidRequest, `userId.tdid`), 'adserver.org', 'TDID');
+ }
+ if (eids.length > 0) {
+ rtbBidRequest.user.ext.eids = eids;
+ }
+
if (rtbBidRequest.imp.length === 0) {
return;
}
@@ -243,4 +259,18 @@ function renderOutstream(bid) {
});
}
+function addExternalUserId(eids, value, source, rtiPartner) {
+ if (utils.isStr(value)) {
+ eids.push({
+ source,
+ uids: [{
+ id: value,
+ ext: {
+ rtiPartner
+ }
+ }]
+ });
+ }
+}
+
registerBidder(spec);
diff --git a/test/spec/modules/gamoshiBidAdapter_spec.js b/test/spec/modules/gamoshiBidAdapter_spec.js
index a2c4eebc213..2d63d47a73e 100644
--- a/test/spec/modules/gamoshiBidAdapter_spec.js
+++ b/test/spec/modules/gamoshiBidAdapter_spec.js
@@ -227,13 +227,49 @@ describe('GamoshiAdapter', function () {
it('builds request with gdpr consent', function () {
let response = spec.buildRequests([bidRequest], bidRequest)[0];
+ expect(response.data.ext.gdpr_consent).to.exist;
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.exist;
+ expect(response.data.user.ext.consent).to.equal('some string');
+ });
+
+ it('build request with ID5 Id', function () {
+ const bidRequestClone = utils.deepClone(bidRequest);
+ bidRequestClone.userId = {};
+ bidRequestClone.userId.id5id = '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', function () {
+ 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', function () {
+ describe('interpretResponse', () => {
const bannerBidRequest = {
'adUnitCode': 'adunit-code',
'auctionId': '1d1a030790a475',
From 2da0604cfc8eacb716b6d560579f5660215f4d57 Mon Sep 17 00:00:00 2001
From: Ankit Prakash
Date: Wed, 2 Oct 2019 16:56:28 -0600
Subject: [PATCH 35/38] schain and digitrust
---
modules/sovrnBidAdapter.js | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/modules/sovrnBidAdapter.js b/modules/sovrnBidAdapter.js
index 8b08b3ad6be..a7084ca7b5f 100644
--- a/modules/sovrnBidAdapter.js
+++ b/modules/sovrnBidAdapter.js
@@ -27,7 +27,11 @@ export const spec = {
const loc = utils.getTopWindowLocation();
let sovrnImps = [];
let iv;
+ let schain;
utils._each(bidReqs, function (bid) {
+ if(bid.schain) {
+ schain = schain || bid.schain;
+ }
iv = iv || utils.getBidIdParameter('iv', bid.params);
bid.sizes = ((utils.isArray(bid.sizes) && utils.isArray(bid.sizes[0])) ? bid.sizes : [bid.sizes])
bid.sizes = bid.sizes.filter(size => utils.isArray(size))
@@ -52,6 +56,14 @@ export const spec = {
}
};
+ if(schain) {
+ sovrnBidReq.source = {
+ ext: {
+ schain
+ }
+ };
+ }
+
if (bidderRequest && bidderRequest.gdprConsent) {
sovrnBidReq.regs = {
ext: {
@@ -63,6 +75,16 @@ export const spec = {
}};
}
+ const bidRequestDigitrust = utils.deepAccess(bidRequest, 'userId.digitrustid.data');
+ if (bidRequestDigitrust && !bidRequestDigitrust.privacy.optout) {
+ sovrnBidReq.user = sovrnBidReq.user || {};
+ sovrnBidReq.user.ext = sovrnBidReq.user.ext || {}
+ sovrnBidReq.user.ext.digitrust = {
+ id: bidRequestDigitrust.id,
+ keyv: bidRequestDigitrust.keyv
+ }
+ }
+
let url = `//ap.lijit.com/rtb/bid?` +
`src=$$REPO_AND_VERSION$$`;
if (iv) url += `&iv=${iv}`;
From 38337c06d3241cfe39cb8f1539dfcbbb2ae9dbb7 Mon Sep 17 00:00:00 2001
From: Unknown
Date: Mon, 7 Oct 2019 14:09:44 -0600
Subject: [PATCH 36/38] pixel beacons
---
modules/sovrnBidAdapter.js | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/modules/sovrnBidAdapter.js b/modules/sovrnBidAdapter.js
index a7084ca7b5f..dc240bfd0ce 100644
--- a/modules/sovrnBidAdapter.js
+++ b/modules/sovrnBidAdapter.js
@@ -139,8 +139,8 @@ export const spec = {
try {
let tracks = []
if (serverResponses && serverResponses.length !== 0 && syncOptions.iframeEnabled) {
- let iidArr = serverResponses.filter(rsp => rsp.body && rsp.body.ext && rsp.body.ext.iid)
- .map(rsp => { return rsp.body.ext.iid });
+ let iidArr = serverResponses.filter(resp => resp.body && resp.body.ext && resp.body.ext.iid)
+ .map(resp => resp.body.ext.iid);
let consentString = '';
if (gdprConsent && gdprConsent.gdprApplies && typeof gdprConsent.consentString === 'string') {
consentString = gdprConsent.consentString
@@ -152,9 +152,17 @@ export const spec = {
});
}
}
- if (errorpxls.length && syncOptions.pixelEnabled) {
- tracks = tracks.concat(errorpxls)
+ if(syncOptions.pixelEnabled) {
+ if (serverResponses && serverResponses.length !== 0) {
+ serverResponses.filter(resp => resp.body && resp.body.ext && resp.body.ext.sync && resp.body.ext.sync.pixels)
+ .map(resp => resp.body.ext.sync.pixels.url)
+ .forEach(url => tracks.push({ type: 'image', url}))
+ }
+ if (errorpxls.length) {
+ tracks = tracks.concat(errorpxls)
+ }
}
+
return tracks
} catch (e) {
if (syncOptions.pixelEnabled) {
From 0dd6eb519a8ea7b3661ba1cf0a9614cf036cca98 Mon Sep 17 00:00:00 2001
From: Unknown
Date: Tue, 8 Oct 2019 13:28:16 -0600
Subject: [PATCH 37/38] unit tests and fixes from testing
---
modules/sovrnBidAdapter.js | 65 ++++++-----
test/spec/modules/sovrnBidAdapter_spec.js | 128 ++++++++++++++++++----
2 files changed, 143 insertions(+), 50 deletions(-)
diff --git a/modules/sovrnBidAdapter.js b/modules/sovrnBidAdapter.js
index dc240bfd0ce..fed3958cf16 100644
--- a/modules/sovrnBidAdapter.js
+++ b/modules/sovrnBidAdapter.js
@@ -28,8 +28,19 @@ export const spec = {
let sovrnImps = [];
let iv;
let schain;
+ let digitrust;
+
utils._each(bidReqs, function (bid) {
- if(bid.schain) {
+ if (!digitrust) {
+ const bidRequestDigitrust = utils.deepAccess(bid, 'userId.digitrustid.data');
+ if (bidRequestDigitrust && (!bidRequestDigitrust.privacy || !bidRequestDigitrust.privacy.optout)) {
+ digitrust = {
+ id: bidRequestDigitrust.id,
+ keyv: bidRequestDigitrust.keyv
+ }
+ }
+ }
+ if (bid.schain) {
schain = schain || bid.schain;
}
iv = iv || utils.getBidIdParameter('iv', bid.params);
@@ -56,7 +67,7 @@ export const spec = {
}
};
- if(schain) {
+ if (schain) {
sovrnBidReq.source = {
ext: {
schain
@@ -75,13 +86,12 @@ export const spec = {
}};
}
- const bidRequestDigitrust = utils.deepAccess(bidRequest, 'userId.digitrustid.data');
- if (bidRequestDigitrust && !bidRequestDigitrust.privacy.optout) {
+ if (digitrust) {
sovrnBidReq.user = sovrnBidReq.user || {};
sovrnBidReq.user.ext = sovrnBidReq.user.ext || {}
sovrnBidReq.user.ext.digitrust = {
- id: bidRequestDigitrust.id,
- keyv: bidRequestDigitrust.keyv
+ id: digitrust.id,
+ keyv: digitrust.keyv
}
}
@@ -138,28 +148,31 @@ export const spec = {
getUserSyncs: function(syncOptions, serverResponses, gdprConsent) {
try {
let tracks = []
- if (serverResponses && serverResponses.length !== 0 && syncOptions.iframeEnabled) {
- let iidArr = serverResponses.filter(resp => resp.body && resp.body.ext && resp.body.ext.iid)
- .map(resp => resp.body.ext.iid);
- let consentString = '';
- if (gdprConsent && gdprConsent.gdprApplies && typeof gdprConsent.consentString === 'string') {
- consentString = gdprConsent.consentString
- }
- if (iidArr[0]) {
- tracks.push({
- type: 'iframe',
- url: '//ap.lijit.com/beacon?informer=' + iidArr[0] + '&gdpr_consent=' + consentString,
- });
+ if (serverResponses && serverResponses.length !== 0) {
+ if (syncOptions.iframeEnabled) {
+ let iidArr = serverResponses.filter(resp => resp.body && resp.body.ext && resp.body.ext.iid)
+ .map(resp => resp.body.ext.iid);
+ let consentString = '';
+ if (gdprConsent && gdprConsent.gdprApplies && typeof gdprConsent.consentString === 'string') {
+ consentString = gdprConsent.consentString
+ }
+ if (iidArr[0]) {
+ tracks.push({
+ type: 'iframe',
+ url: '//ap.lijit.com/beacon?informer=' + iidArr[0] + '&gdpr_consent=' + consentString,
+ });
+ }
}
- }
- if(syncOptions.pixelEnabled) {
- if (serverResponses && serverResponses.length !== 0) {
+
+ if (syncOptions.pixelEnabled) {
serverResponses.filter(resp => resp.body && resp.body.ext && resp.body.ext.sync && resp.body.ext.sync.pixels)
- .map(resp => resp.body.ext.sync.pixels.url)
- .forEach(url => tracks.push({ type: 'image', url}))
- }
- if (errorpxls.length) {
- tracks = tracks.concat(errorpxls)
+ .flatMap(resp => resp.body.ext.sync.pixels)
+ .map(pixel => pixel.url)
+ .forEach(url => tracks.push({ type: 'image', url }))
+
+ if (errorpxls.length) {
+ tracks = tracks.concat(errorpxls)
+ }
}
}
diff --git a/test/spec/modules/sovrnBidAdapter_spec.js b/test/spec/modules/sovrnBidAdapter_spec.js
index 7179ec00bc3..5f385008f54 100644
--- a/test/spec/modules/sovrnBidAdapter_spec.js
+++ b/test/spec/modules/sovrnBidAdapter_spec.js
@@ -1,7 +1,6 @@
-import { expect } from 'chai';
-import { spec, LogError } from 'modules/sovrnBidAdapter';
-import { newBidder } from 'src/adapters/bidderFactory';
-import { SSL_OP_SINGLE_ECDH_USE } from 'constants';
+import {expect} from 'chai';
+import {LogError, spec} from 'modules/sovrnBidAdapter';
+import {newBidder} from 'src/adapters/bidderFactory';
const ENDPOINT = `//ap.lijit.com/rtb/bid?src=$$REPO_AND_VERSION$$`;
@@ -128,13 +127,12 @@ describe('sovrnBidAdapter', function() {
};
bidderRequest.bids = bidRequests;
- const request = spec.buildRequests(bidRequests, bidderRequest);
- const payload = JSON.parse(request.data);
+ const data = JSON.parse(spec.buildRequests(bidRequests, bidderRequest).data);
- expect(payload.regs.ext.gdpr).to.exist.and.to.be.a('number');
- expect(payload.regs.ext.gdpr).to.equal(1);
- expect(payload.user.ext.consent).to.exist.and.to.be.a('string');
- expect(payload.user.ext.consent).to.equal(consentString);
+ 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('converts tagid to string', function () {
@@ -156,7 +154,68 @@ describe('sovrnBidAdapter', function() {
const request = spec.buildRequests(ivBidRequests);
expect(request.data).to.contain('"tagid":"403370"')
- })
+ });
+
+ it('should add schain if present', () => {
+ 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(bidRequests);
+ const data = JSON.parse(spec.buildRequests(schainRequests).data);
+
+ expect(data.source.ext.schain.nodes.length).to.equal(1)
+ });
+
+ it('should add digitrust data if present', () => {
+ const digitrustRequests = [{
+ 'bidder': 'sovrn',
+ 'params': {
+ 'tagid': 403370
+ },
+ 'adUnitCode': 'adunit-code',
+ 'sizes': [
+ [300, 250],
+ [300, 600]
+ ],
+ 'bidId': '30b31c1838de1e',
+ 'bidderRequestId': '22edbae2733bf6',
+ 'auctionId': '1d1a030790a475',
+ 'userId': {
+ 'digitrustid': {
+ 'data': {
+ 'id': 'digitrust-id-123',
+ 'keyv': 4
+ }
+ }
+ }
+ }].concat(bidRequests);
+ const data = JSON.parse(spec.buildRequests(digitrustRequests).data);
+
+ expect(data.user.ext.digitrust.id).to.equal('digitrust-id-123');
+ expect(data.user.ext.digitrust.keyv).to.equal(4);
+ });
});
describe('interpretResponse', function () {
@@ -254,8 +313,8 @@ describe('sovrnBidAdapter', function() {
});
describe('getUserSyncs ', () => {
- let syncOptions = {iframeEnabled: true, pixelEnabled: true};
- let iframeDisabledSyncOptions = {iframeEnabled: false, pixelEnabled: true};
+ let syncOptions = { iframeEnabled: true, pixelEnabled: false };
+ let iframeDisabledSyncOptions = { iframeEnabled: false, pixelEnabled: false };
let serverResponse = [
{
'body': {
@@ -287,33 +346,54 @@ describe('sovrnBidAdapter', function() {
}
],
'ext': {
- 'iid': 13487408
+ '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', () => {
- let expectedReturnStatement = [
+ const expectedReturnStatement = [
{
'type': 'iframe',
'url': '//ap.lijit.com/beacon?informer=13487408&gdpr_consent=',
}
- ]
- let returnStatement = spec.getUserSyncs(syncOptions, serverResponse);
+ ];
+ const returnStatement = spec.getUserSyncs(syncOptions, serverResponse);
expect(returnStatement[0]).to.deep.equal(expectedReturnStatement[0]);
- })
+ });
it('should not return if iid missing on server response', () => {
- let returnStatement = spec.getUserSyncs(syncOptions, [])
+ const returnStatement = spec.getUserSyncs(syncOptions, []);
expect(returnStatement).to.be.empty;
- })
+ });
it('should not return if iframe syncs disabled', () => {
- let returnStatement = spec.getUserSyncs(iframeDisabledSyncOptions, serverResponse)
- expect(returnStatement).to.be.empty
- })
- })
+ const returnStatement = spec.getUserSyncs(iframeDisabledSyncOptions, serverResponse);
+ expect(returnStatement).to.be.empty;
+ });
+
+ it('should include pixel syncs', () => {
+ let pixelEnabledOptions = { iframeEnabled: false, pixelEnabled: true };
+ const returnStatement = spec.getUserSyncs(pixelEnabledOptions, serverResponse);
+ console.log(returnStatement)
+ expect(returnStatement.length).to.equal(2);
+ expect(returnStatement).to.deep.include.members([{ type: 'image', url: 'http://idprovider1.com' },
+ { type: 'image', url: 'http://idprovider2.com' }]);
+ });
+ });
+
describe('LogError', () => {
it('should build and append an error object', () => {
const thrown = {
From 1bbab9e28083f1f10e134d2c49678f8baab63750 Mon Sep 17 00:00:00 2001
From: Unknown
Date: Wed, 16 Oct 2019 14:17:00 -0600
Subject: [PATCH 38/38] Prebid 3.0 updates
---
modules/sovrnBidAdapter.js | 73 +++-------
test/spec/modules/sovrnBidAdapter_spec.js | 162 ++++++++++------------
2 files changed, 95 insertions(+), 140 deletions(-)
diff --git a/modules/sovrnBidAdapter.js b/modules/sovrnBidAdapter.js
index fed3958cf16..b953f3bc19f 100644
--- a/modules/sovrnBidAdapter.js
+++ b/modules/sovrnBidAdapter.js
@@ -1,8 +1,6 @@
import * as utils from '../src/utils'
import { registerBidder } from '../src/adapters/bidderFactory'
import { BANNER } from '../src/mediaTypes'
-const errorUrl = 'https://pcb.aws.lijit.com/c'
-let errorpxls = []
export const spec = {
code: 'sovrn',
@@ -24,7 +22,6 @@ export const spec = {
*/
buildRequests: function(bidReqs, bidderRequest) {
try {
- const loc = utils.getTopWindowLocation();
let sovrnImps = [];
let iv;
let schain;
@@ -44,9 +41,11 @@ export const spec = {
schain = schain || bid.schain;
}
iv = iv || utils.getBidIdParameter('iv', bid.params);
- 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)}))
+
+ 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)}))
sovrnImps.push({
id: bid.bidId,
banner: {
@@ -58,12 +57,19 @@ export const spec = {
bidfloor: utils.getBidIdParameter('bidfloor', bid.params)
});
});
+
+ const page = bidderRequest.refererInfo.referer
+ // clever trick to get the domain
+ const el = document.createElement('a');
+ el.href = page;
+ const domain = el.hostname;
+
const sovrnBidReq = {
id: utils.getUniqueIdentifierStr(),
imp: sovrnImps,
site: {
- domain: loc.host,
- page: loc.host + loc.pathname + loc.search + loc.hash
+ page,
+ domain
}
};
@@ -95,7 +101,7 @@ export const spec = {
}
}
- let url = `//ap.lijit.com/rtb/bid?` +
+ let url = `https://ap.lijit.com/rtb/bid?` +
`src=$$REPO_AND_VERSION$$`;
if (iv) url += `&iv=${iv}`;
@@ -106,7 +112,8 @@ export const spec = {
options: {contentType: 'text/plain'}
}
} catch (e) {
- new LogError(e, {bidReqs, bidderRequest}).append()
+ console.log('error in build:')
+ console.log(e)
}
},
@@ -141,7 +148,8 @@ export const spec = {
}
return sovrnBidResponses
} catch (e) {
- new LogError(e, {id, seatbid}).append()
+ console.log('error in interpret:')
+ console.log(e)
}
},
@@ -169,57 +177,14 @@ export const spec = {
.flatMap(resp => resp.body.ext.sync.pixels)
.map(pixel => pixel.url)
.forEach(url => tracks.push({ type: 'image', url }))
-
- if (errorpxls.length) {
- tracks = tracks.concat(errorpxls)
- }
}
}
return tracks
} catch (e) {
- if (syncOptions.pixelEnabled) {
- return errorpxls
- }
return []
}
},
}
-export class LogError {
- constructor(e, data) {
- utils.logError(e)
- this.error = {}
- this.error.t = utils.timestamp()
- this.error.m = e.message
- this.error.s = e.stack
- this.error.d = data
- this.error.v = $$REPO_AND_VERSION$$
- this.error.u = utils.getTopWindowLocation().href
- this.error.ua = navigator.userAgent
- }
- buildErrorString(obj) {
- return errorUrl + '?b=' + btoa(JSON.stringify(obj))
- }
- append() {
- let errstr = this.buildErrorString(this.error)
- if (errstr.length > 2083) {
- delete this.error.d
- errstr = this.buildErrorString(this.error)
- if (errstr.length > 2083) {
- delete this.error.s
- errstr = this.buildErrorString(this.error)
- if (errstr.length > 2083) {
- errstr = this.buildErrorString({m: 'unknown error message', t: this.error.t, u: this.error.u})
- }
- }
- }
- let obj = {type: 'image', url: errstr}
- errorpxls.push(obj)
- }
- static getErrPxls() {
- return errorpxls
- }
-}
-
registerBidder(spec);
diff --git a/test/spec/modules/sovrnBidAdapter_spec.js b/test/spec/modules/sovrnBidAdapter_spec.js
index 5f385008f54..af27e6e74a6 100644
--- a/test/spec/modules/sovrnBidAdapter_spec.js
+++ b/test/spec/modules/sovrnBidAdapter_spec.js
@@ -2,7 +2,7 @@ import {expect} from 'chai';
import {LogError, spec} from 'modules/sovrnBidAdapter';
import {newBidder} from 'src/adapters/bidderFactory';
-const ENDPOINT = `//ap.lijit.com/rtb/bid?src=$$REPO_AND_VERSION$$`;
+const ENDPOINT = `https://ap.lijit.com/rtb/bid?src=$$REPO_AND_VERSION$$`;
describe('sovrnBidAdapter', function() {
const adapter = newBidder(spec);
@@ -54,8 +54,12 @@ describe('sovrnBidAdapter', function() {
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475'
}];
-
- const request = spec.buildRequests(bidRequests);
+ const bidderRequest = {
+ refererInfo: {
+ referer: 'http://example.com/page.html',
+ }
+ };
+ const request = spec.buildRequests(bidRequests, bidderRequest);
it('sends bid request to our endpoint via POST', function () {
expect(request.method).to.equal('POST');
@@ -72,7 +76,7 @@ describe('sovrnBidAdapter', function() {
expect(payload.imp[0].banner.h).to.equal(1)
})
- it('accepts a single array as a size', function() {
+ it('accepts a single array as a size', () => {
const singleSize = [{
'bidder': 'sovrn',
'params': {
@@ -84,8 +88,13 @@ describe('sovrnBidAdapter', function() {
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475'
- }];
- const request = spec.buildRequests(singleSize)
+ }]
+ const bidderRequest = {
+ refererInfo: {
+ referer: 'http://example.com/page.html',
+ }
+ }
+ 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)
@@ -108,7 +117,12 @@ describe('sovrnBidAdapter', function() {
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475'
}];
- const request = spec.buildRequests(ivBidRequests);
+ const bidderRequest = {
+ refererInfo: {
+ referer: 'http://example.com/page.html',
+ }
+ };
+ const request = spec.buildRequests(ivBidRequests, bidderRequest);
expect(request.url).to.contain('iv=vet')
});
@@ -120,9 +134,12 @@ describe('sovrnBidAdapter', function() {
'auctionId': '1d1a030790a475',
'bidderRequestId': '22edbae2733bf6',
'timeout': 3000,
- 'gdprConsent': {
+ gdprConsent: {
consentString: consentString,
gdprApplies: true
+ },
+ refererInfo: {
+ referer: 'http://example.com/page.html',
}
};
bidderRequest.bids = bidRequests;
@@ -151,7 +168,12 @@ describe('sovrnBidAdapter', function() {
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475'
}];
- const request = spec.buildRequests(ivBidRequests);
+ const bidderRequest = {
+ refererInfo: {
+ referer: 'http://example.com/page.html',
+ }
+ };
+ const request = spec.buildRequests(ivBidRequests, bidderRequest);
expect(request.data).to.contain('"tagid":"403370"')
});
@@ -183,7 +205,12 @@ describe('sovrnBidAdapter', function() {
]
}
}].concat(bidRequests);
- const data = JSON.parse(spec.buildRequests(schainRequests).data);
+ 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)
});
@@ -211,7 +238,12 @@ describe('sovrnBidAdapter', function() {
}
}
}].concat(bidRequests);
- const data = JSON.parse(spec.buildRequests(digitrustRequests).data);
+ const bidderRequest = {
+ refererInfo: {
+ referer: 'http://example.com/page.html',
+ }
+ };
+ const data = JSON.parse(spec.buildRequests(digitrustRequests, bidderRequest).data);
expect(data.user.ext.digitrust.id).to.equal('digitrust-id-123');
expect(data.user.ext.digitrust.keyv).to.equal(4);
@@ -394,84 +426,42 @@ describe('sovrnBidAdapter', function() {
});
});
- describe('LogError', () => {
- it('should build and append an error object', () => {
- const thrown = {
- message: 'message',
- stack: 'stack'
- }
- const data = {name: 'Oscar Hathenswiotch'}
- const err = new LogError(thrown, data)
- err.append()
- const errList = LogError.getErrPxls()
- expect(errList.length).to.equal(1)
- const errdata = JSON.parse(atob(errList[0].url.split('=')[1]))
- expect(errdata.d.name).to.equal('Oscar Hathenswiotch')
- })
- it('should drop data when there is too much', () => {
- const thrown = {
- message: 'message',
- stack: 'stack'
- }
- const tooLong = () => {
- let str = ''
- for (let i = 0; i < 10000; i++) {
- str = str + String.fromCharCode(i % 100)
- }
- return str
- }
- const data = {name: 'Oscar Hathenswiotch', tooLong: tooLong()}
- const err = new LogError(thrown, data)
- err.append()
- const errList = LogError.getErrPxls()
- expect(errList.length).to.equal(2)
- const errdata = JSON.parse(atob(errList[1].url.split('=')[1]))
- expect(errdata.d).to.be.an('undefined')
- })
- it('should drop data and stack when there is too much', () => {
- const thrown = {
- message: 'message',
- stack: 'stack'
- }
- const tooLong = () => {
- let str = ''
- for (let i = 0; i < 10000; i++) {
- str = str + String.fromCharCode(i % 100)
+ describe('prebid 3 upgrade', () => {
+ const bidRequests = [{
+ 'bidder': 'sovrn',
+ 'params': {
+ 'tagid': '403370'
+ },
+ 'adUnitCode': 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [
+ [300, 250],
+ [300, 600]
+ ]
}
- return str
+ },
+ 'bidId': '30b31c1838de1e',
+ 'bidderRequestId': '22edbae2733bf6',
+ 'auctionId': '1d1a030790a475'
+ }];
+ const bidderRequest = {
+ refererInfo: {
+ referer: 'http://example.com/page.html',
}
- const data = {name: 'Oscar Hathenswiotch'}
- thrown.stack = tooLong()
- const err = new LogError(thrown, data)
- err.append()
- const errList = LogError.getErrPxls()
- expect(errList.length).to.equal(3)
- const errdata = JSON.parse(atob(errList[2].url.split('=')[1]))
- expect(errdata.d).to.be.an('undefined')
- expect(errdata.s).to.be.an('undefined')
+ };
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ const payload = JSON.parse(request.data);
+
+ it('gets sizes from mediaTypes.banner', () => {
+ 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('should drop send a reduced message when other reduction methods fail', () => {
- const thrown = {
- message: 'message',
- stack: 'stack'
- }
- const tooLong = () => {
- let str = ''
- for (let i = 0; i < 10000; i++) {
- str = str + String.fromCharCode(i % 100)
- }
- return str
- }
- const data = {name: 'Oscar Hathenswiotch'}
- thrown.message = tooLong()
- const err = new LogError(thrown, data)
- err.append()
- const errList = LogError.getErrPxls()
- expect(errList.length).to.equal(4)
- const errdata = JSON.parse(atob(errList[3].url.split('=')[1]))
- expect(errdata.d).to.be.an('undefined')
- expect(errdata.s).to.be.an('undefined')
- expect(errdata.m).to.equal('unknown error message')
+
+ it('gets correct site info', () => {
+ expect(payload.site.page).to.equal('http://example.com/page.html');
+ expect(payload.site.domain).to.equal('example.com');
})
})
})