From 21bab6bdd65f8d539c7df0bda98571f21b39a073 Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Tue, 17 Oct 2017 18:20:54 -0400 Subject: [PATCH 01/16] Adding files associated with the trion adapter update to the newest prebid version(1.0). --- modules/trionBidAdapter.js | 138 ++++++++++++++ modules/trionBidAdapter.md | 33 ++++ test/spec/modules/trionBidAdapter_spec.js | 222 ++++++++++++++++++++++ 3 files changed, 393 insertions(+) create mode 100644 modules/trionBidAdapter.js create mode 100644 modules/trionBidAdapter.md create mode 100644 test/spec/modules/trionBidAdapter_spec.js diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js new file mode 100644 index 00000000000..9cd75bee4a2 --- /dev/null +++ b/modules/trionBidAdapter.js @@ -0,0 +1,138 @@ +import * as utils from 'src/utils'; +import {registerBidder} from 'src/adapters/bidderFactory'; + +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) { + var bidRequests = []; + + for (var i = 0; i < validBidRequests.length; i++) { + var bid = validBidRequests[i]; + + var trionUrlParams = buildTrionUrlParams(bid); + + 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; + + if (trionResponseObj && trionResponseObj.bidId && bidRequest) { + var result = trionResponseObj.result; + + if (result && result.cpm && result.placeBid && result.ad) { + var cpm = parseInt(result.cpm, 10) / 100; + + bid.requestId = bidRequest.bidId; + bid.bidderCode = bidRequest.bidder; + bid.cpm = cpm; + bid.ad = result.ad; + bid.width = result.width; + bid.height = result.height; + bidResponses.push(bid); + } + } + + return bidResponses; + }, + getUserSyncs: function getUserSyncs(syncOptions) { + window.addEventListener('message', acceptPostMessage); + var unParsedPubAndSection = getStorageData(BASE_KEY + 'lps') || ':'; + var pubId = unParsedPubAndSection.split(':')[0] || -1; + var sectionId = unParsedPubAndSection.split(':')[1] || -1; + var url = utils.getTopWindowUrl(); + var syncString = `?p=${pubId}&s=${sectionId}&u=${url}`; + return [{ + type: 'iframe', + url: USER_SYNC_URL + syncString + }]; + } + +}; +registerBidder(spec); + +function buildTrionUrlParams(bid) { + var pubId = utils.getBidIdParameter('pubId', bid.params); + var sectionId = utils.getBidIdParameter('sectionId', bid.params); + var re = utils.getBidIdParameter('re', bid.params); + var url = utils.getTopWindowUrl(); + var sizes = utils.parseSizesInput(bid.sizes).join(','); + + var int_t = window.TR_INT_T && window.TR_INT_T != -1 ? window.TR_INT_T : null; + if (!int_t) { + int_t = getStorageData(BASE_KEY + 'int_t'); + } + if (int_t) { + setStorageData(BASE_KEY + 'int_t', int_t) + } + 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, 're', re); + if (url) { + trionUrl += 'url=' + url + '&'; + } + if (sizes) { + trionUrl += 'sizes=' + sizes + '&'; + } + if (int_t) { + trionUrl = utils.tryAppendQueryString(trionUrl, 'int_t', encodeURIComponent(int_t)); + } + + // remove the trailing "&" + if (trionUrl.lastIndexOf('&') === trionUrl.length - 1) { + trionUrl = trionUrl.substring(0, trionUrl.length - 1); + } + return trionUrl; +} + +export function getStorageData(key) { + var item = null; + try { + if (window.localStorage) { + item = window.localStorage.getItem(key); + } + } catch (e) { + } + return item; +} + +export function setStorageData(key, item) { + try { + if (window.localStorage) { + window.localStorage.setItem(key, item); + } + } catch (e) { + } +} + +export function acceptPostMessage(e) { + var message = e.data || ''; + if (message.indexOf(BASE_KEY + 'userId') !== 0) { + return; + } + var int_t = message.split(BASE_KEY + 'userId=')[1]; + if (int_t) { + setStorageData(BASE_KEY + 'int_t', int_t); + } +} diff --git a/modules/trionBidAdapter.md b/modules/trionBidAdapter.md new file mode 100644 index 00000000000..ac21a407144 --- /dev/null +++ b/modules/trionBidAdapter.md @@ -0,0 +1,33 @@ +# 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/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js new file mode 100644 index 00000000000..70b5b019161 --- /dev/null +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -0,0 +1,222 @@ +import {expect} from 'chai'; +import * as utils from 'src/utils'; +import {spec, acceptPostMessage, getStorageData, setStorageData} from 'modules/trionBidAdapter'; +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' + }, + adUnitCode: 'adunit-code', + sizes: [[300, 250], [300, 600]], + bidId: 'test-bid-id', + bidRequest: 'test-bid-request' +}; + +const TRION_BID_REQUEST = [TRION_BID]; + +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' + } + +}; + +describe('Trion adapter tests', () => { + let adapter; + + beforeEach(() => { + // adapter = trionAdapter.createNew(); + sinon.stub(document.body, 'appendChild'); + }); + + afterEach(() => 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', () => { + it('should return bids requests with empty params', function () { + var 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'); + }); + + it('should call buildRequests with the correct optional params', function () { + let params = TRION_BID_REQUEST[0].params; + params.re = 1; + let bidRequests = spec.buildRequests(TRION_BID_REQUEST); + + let bidUrlParams = bidRequests[0].data; + expect(bidUrlParams).to.include('re=1'); + expect(bidUrlParams).to.include(utils.getTopWindowUrl()); + delete params.re; + }); + }); + + describe('interpretResponse', () => { + 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; + var response = spec.interpretResponse(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; + var response = spec.interpretResponse(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; + var response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + expect(response).to.deep.equal([]); + TRION_BID_RESPONSE.result.ad = 'test'; + }); + + it('bid response is formatted correctly', function () { + var response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + expect(response[0].bidderCode).to.equal('trion'); + }); + + 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; + var response = spec.interpretResponse(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; + var response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + expect(response[0].cpm).to.equal(bidCpm); + TRION_BID_RESPONSE.result.cpm = 100; + }); + }); + + describe('getUserSyncs', () => { + const USER_SYNC_URL = 'https://in-appadvertising.com/api/userSync.html'; + const BASE_KEY = '_trion_'; + + beforeEach(() => { + delete window.TR_INT_T; + }); + + it('trion int is included in bid url', () => { + 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', () => { + let syncs = spec.getUserSyncs(); + let url = utils.getTopWindowUrl(); + let pubId = 1; + let sectionId = 2; + var syncString = `?p=${pubId}&s=${sectionId}&u=${url}`; + expect(syncs[0]).to.deep.equal({type: 'iframe', url: USER_SYNC_URL + syncString}); + }); + + it('should except posted messages from user sync script', () => { + 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', () => { + 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); + }); + }); +}); From 3abcf64417e19fd861d5fab3d12e2b66d277021a Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Wed, 18 Oct 2017 11:55:24 -0400 Subject: [PATCH 02/16] Updating pull request with safer checks for user sync and general clean up/consistency of tests. --- modules/trionBidAdapter.js | 35 +++++++++++----- test/spec/modules/trionBidAdapter_spec.js | 50 +++++++++++------------ 2 files changed, 50 insertions(+), 35 deletions(-) diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js index 9cd75bee4a2..1a2d14a33ca 100644 --- a/modules/trionBidAdapter.js +++ b/modules/trionBidAdapter.js @@ -53,21 +53,27 @@ export const spec = { return bidResponses; }, getUserSyncs: function getUserSyncs(syncOptions) { - window.addEventListener('message', acceptPostMessage); - var unParsedPubAndSection = getStorageData(BASE_KEY + 'lps') || ':'; - var pubId = unParsedPubAndSection.split(':')[0] || -1; - var sectionId = unParsedPubAndSection.split(':')[1] || -1; - var url = utils.getTopWindowUrl(); - var syncString = `?p=${pubId}&s=${sectionId}&u=${url}`; - return [{ - type: 'iframe', - url: USER_SYNC_URL + syncString - }]; + if (syncOptions.iframeEnabled) { + handlePostMessage(); + return [{ + type: 'iframe', + url: getSyncUrl() + }]; + } } }; registerBidder(spec); +function getSyncUrl() { + var unParsedPubAndSection = getStorageData(BASE_KEY + 'lps') || ':'; + var pubSectionArray = unParsedPubAndSection.split(':') || []; + var pubId = pubSectionArray[0] || -1; + var sectionId = pubSectionArray[1] || -1; + var url = utils.getTopWindowUrl(); + return USER_SYNC_URL + `?p=${pubId}&s=${sectionId}&u=${url}`; +} + function buildTrionUrlParams(bid) { var pubId = utils.getBidIdParameter('pubId', bid.params); var sectionId = utils.getBidIdParameter('sectionId', bid.params); @@ -106,6 +112,15 @@ function buildTrionUrlParams(bid) { return trionUrl; } +function handlePostMessage() { + try { + if (window.addEventListener) { + window.addEventListener('message', acceptPostMessage); + } + } catch (e) { + } +} + export function getStorageData(key) { var item = null; try { diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index 70b5b019161..2785b4be332 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -45,12 +45,12 @@ describe('Trion adapter tests', () => { afterEach(() => document.body.appendChild.restore()); - describe('isBidRequestValid', function() { - it('should return true with correct params', function () { + describe('isBidRequestValid', () => { + it('should return true with correct params', () => { expect(spec.isBidRequestValid(TRION_BID)).to.equal(true); }); - it('should return false when params are missing', function () { + it('should return false when params are missing', () => { TRION_BID.params = {}; expect(spec.isBidRequestValid(TRION_BID)).to.equal(false); @@ -60,7 +60,7 @@ describe('Trion adapter tests', () => { }; }); - it('should return false when pubId is missing', function () { + it('should return false when pubId is missing', () => { TRION_BID.params = { sectionId: '2' }; @@ -72,7 +72,7 @@ describe('Trion adapter tests', () => { }; }); - it('should return false when sectionId is missing', function () { + it('should return false when sectionId is missing', () => { TRION_BID.params = { pubId: '1' }; @@ -86,19 +86,19 @@ describe('Trion adapter tests', () => { }); describe('buildRequests', () => { - it('should return bids requests with empty params', function () { - var bidRequests = spec.buildRequests([]); + it('should return bids requests with empty params', () => { + let bidRequests = spec.buildRequests([]); expect(bidRequests.length).to.equal(0); }); - it('should include the base bidrequest url', function () { + it('should include the base bidrequest url', () => { 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 () { + it('should call buildRequests with the correct required params', () => { let bidRequests = spec.buildRequests(TRION_BID_REQUEST); let bidUrlParams = bidRequests[0].data; @@ -107,7 +107,7 @@ describe('Trion adapter tests', () => { expect(bidUrlParams).to.include('sizes=300x250,300x600'); }); - it('should call buildRequests with the correct optional params', function () { + it('should call buildRequests with the correct optional params', () => { let params = TRION_BID_REQUEST[0].params; params.re = 1; let bidRequests = spec.buildRequests(TRION_BID_REQUEST); @@ -120,55 +120,55 @@ describe('Trion adapter tests', () => { }); describe('interpretResponse', () => { - it('when there is no response do not bid', function () { + it('when there is no response do not bid', () => { let response = spec.interpretResponse(null, {bidRequest: TRION_BID}); expect(response).to.deep.equal([]); }); - it('when place bid is returned as false', function () { + it('when place bid is returned as false', () => { TRION_BID_RESPONSE.result.placeBid = false; - var response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + let response = spec.interpretResponse(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 () { + it('when no cpm is in the response', () => { TRION_BID_RESPONSE.result.cpm = 0; - var response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + let response = spec.interpretResponse(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 () { + it('when no ad is in the response', () => { TRION_BID_RESPONSE.result.ad = null; - var response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); expect(response).to.deep.equal([]); TRION_BID_RESPONSE.result.ad = 'test'; }); - it('bid response is formatted correctly', function () { - var response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + it('bid response is formatted correctly', () => { + let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); expect(response[0].bidderCode).to.equal('trion'); }); - it('height and width are appropriately set', function () { + it('height and width are appropriately set', () => { let bidWidth = '1'; let bidHeight = '2'; TRION_BID_RESPONSE.result.width = bidWidth; TRION_BID_RESPONSE.result.height = bidHeight; - var response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + let response = spec.interpretResponse(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 () { + it('cpm is properly set and transformed to cents', () => { let bidCpm = 2; TRION_BID_RESPONSE.result.cpm = bidCpm * 100; - var response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); expect(response[0].cpm).to.equal(bidCpm); TRION_BID_RESPONSE.result.cpm = 100; }); @@ -192,11 +192,11 @@ describe('Trion adapter tests', () => { }); it('should register trion user script', () => { - let syncs = spec.getUserSyncs(); + let syncs = spec.getUserSyncs({iframeEnabled: true}); let url = utils.getTopWindowUrl(); let pubId = 1; let sectionId = 2; - var syncString = `?p=${pubId}&s=${sectionId}&u=${url}`; + let syncString = `?p=${pubId}&s=${sectionId}&u=${url}`; expect(syncs[0]).to.deep.equal({type: 'iframe', url: USER_SYNC_URL + syncString}); }); From 0c040fc3879eb5e71f6d63d1ada6e00f929e5ddc Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Mon, 13 Nov 2017 10:21:54 -0500 Subject: [PATCH 03/16] removing a call to bidder code for pull request review. also removing the test that requires it --- modules/trionBidAdapter.js | 1 - test/spec/modules/trionBidAdapter_spec.js | 5 ----- 2 files changed, 6 deletions(-) diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js index 1a2d14a33ca..c6de6fcbb2d 100644 --- a/modules/trionBidAdapter.js +++ b/modules/trionBidAdapter.js @@ -41,7 +41,6 @@ export const spec = { var cpm = parseInt(result.cpm, 10) / 100; bid.requestId = bidRequest.bidId; - bid.bidderCode = bidRequest.bidder; bid.cpm = cpm; bid.ad = result.ad; bid.width = result.width; diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index 2785b4be332..77f6bf61616 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -148,11 +148,6 @@ describe('Trion adapter tests', () => { TRION_BID_RESPONSE.result.ad = 'test'; }); - it('bid response is formatted correctly', () => { - let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); - expect(response[0].bidderCode).to.equal('trion'); - }); - it('height and width are appropriately set', () => { let bidWidth = '1'; let bidHeight = '2'; From 324d15785fb61c92db9c0a37f1001f47721e3a25 Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Tue, 5 Dec 2017 16:59:04 -0500 Subject: [PATCH 04/16] there were some changes to the bid factory after our initial release that we didn't account for. Changing adapter to account for response body and required params. --- modules/trionBidAdapter.js | 9 +++++++-- test/spec/modules/trionBidAdapter_spec.js | 10 +++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js index c6de6fcbb2d..c2488bd351a 100644 --- a/modules/trionBidAdapter.js +++ b/modules/trionBidAdapter.js @@ -33,9 +33,10 @@ export const spec = { var bid = {}; var bidResponses = []; var bidRequest = request.bidRequest; + var responseBody = trionResponseObj ? trionResponseObj.body : {}; - if (trionResponseObj && trionResponseObj.bidId && bidRequest) { - var result = trionResponseObj.result; + if (responseBody && responseBody.bidId && bidRequest) { + var result = responseBody.result; if (result && result.cpm && result.placeBid && result.ad) { var cpm = parseInt(result.cpm, 10) / 100; @@ -45,6 +46,10 @@ export const spec = { 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); } } diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index 77f6bf61616..559122a2772 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -127,7 +127,7 @@ describe('Trion adapter tests', () => { it('when place bid is returned as false', () => { TRION_BID_RESPONSE.result.placeBid = false; - let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + let response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); expect(response).to.deep.equal([]); @@ -136,14 +136,14 @@ describe('Trion adapter tests', () => { it('when no cpm is in the response', () => { TRION_BID_RESPONSE.result.cpm = 0; - let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + 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', () => { TRION_BID_RESPONSE.result.ad = null; - let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + let response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); expect(response).to.deep.equal([]); TRION_BID_RESPONSE.result.ad = 'test'; }); @@ -153,7 +153,7 @@ describe('Trion adapter tests', () => { let bidHeight = '2'; TRION_BID_RESPONSE.result.width = bidWidth; TRION_BID_RESPONSE.result.height = bidHeight; - let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + 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'; @@ -163,7 +163,7 @@ describe('Trion adapter tests', () => { it('cpm is properly set and transformed to cents', () => { let bidCpm = 2; TRION_BID_RESPONSE.result.cpm = bidCpm * 100; - let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + let response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); expect(response[0].cpm).to.equal(bidCpm); TRION_BID_RESPONSE.result.cpm = 100; }); From bb5f8c7e56a9c73200b96994321a93402465e4dc Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Tue, 5 Dec 2017 17:13:54 -0500 Subject: [PATCH 05/16] Revert "there were some changes to the bid factory after our initial release that we didn't account for. Changing adapter to account for response body and required params." This reverts commit 324d15785fb61c92db9c0a37f1001f47721e3a25. --- modules/trionBidAdapter.js | 9 ++------- test/spec/modules/trionBidAdapter_spec.js | 10 +++++----- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js index c2488bd351a..c6de6fcbb2d 100644 --- a/modules/trionBidAdapter.js +++ b/modules/trionBidAdapter.js @@ -33,10 +33,9 @@ export const spec = { var bid = {}; var bidResponses = []; var bidRequest = request.bidRequest; - var responseBody = trionResponseObj ? trionResponseObj.body : {}; - if (responseBody && responseBody.bidId && bidRequest) { - var result = responseBody.result; + if (trionResponseObj && trionResponseObj.bidId && bidRequest) { + var result = trionResponseObj.result; if (result && result.cpm && result.placeBid && result.ad) { var cpm = parseInt(result.cpm, 10) / 100; @@ -46,10 +45,6 @@ export const spec = { 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); } } diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index 559122a2772..77f6bf61616 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -127,7 +127,7 @@ describe('Trion adapter tests', () => { it('when place bid is returned as false', () => { TRION_BID_RESPONSE.result.placeBid = false; - let response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); + let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); expect(response).to.deep.equal([]); @@ -136,14 +136,14 @@ describe('Trion adapter tests', () => { it('when no cpm is in the response', () => { TRION_BID_RESPONSE.result.cpm = 0; - let response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); + let response = spec.interpretResponse(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', () => { TRION_BID_RESPONSE.result.ad = null; - let response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); + let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); expect(response).to.deep.equal([]); TRION_BID_RESPONSE.result.ad = 'test'; }); @@ -153,7 +153,7 @@ describe('Trion adapter tests', () => { 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}); + let response = spec.interpretResponse(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'; @@ -163,7 +163,7 @@ describe('Trion adapter tests', () => { it('cpm is properly set and transformed to cents', () => { let bidCpm = 2; TRION_BID_RESPONSE.result.cpm = bidCpm * 100; - let response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); + let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); expect(response[0].cpm).to.equal(bidCpm); TRION_BID_RESPONSE.result.cpm = 100; }); From 8d67f6369d4abffc35410a96f4cf5bb06e0c51bf Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Tue, 5 Dec 2017 17:26:10 -0500 Subject: [PATCH 06/16] there were some changes to the bid factory after our initial release that we didn't account for. Changing adapter to account for response body and required params. --- modules/trionBidAdapter.js | 9 +++++++-- test/spec/modules/trionBidAdapter_spec.js | 10 +++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js index c6de6fcbb2d..c2488bd351a 100644 --- a/modules/trionBidAdapter.js +++ b/modules/trionBidAdapter.js @@ -33,9 +33,10 @@ export const spec = { var bid = {}; var bidResponses = []; var bidRequest = request.bidRequest; + var responseBody = trionResponseObj ? trionResponseObj.body : {}; - if (trionResponseObj && trionResponseObj.bidId && bidRequest) { - var result = trionResponseObj.result; + if (responseBody && responseBody.bidId && bidRequest) { + var result = responseBody.result; if (result && result.cpm && result.placeBid && result.ad) { var cpm = parseInt(result.cpm, 10) / 100; @@ -45,6 +46,10 @@ export const spec = { 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); } } diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index 77f6bf61616..559122a2772 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -127,7 +127,7 @@ describe('Trion adapter tests', () => { it('when place bid is returned as false', () => { TRION_BID_RESPONSE.result.placeBid = false; - let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + let response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); expect(response).to.deep.equal([]); @@ -136,14 +136,14 @@ describe('Trion adapter tests', () => { it('when no cpm is in the response', () => { TRION_BID_RESPONSE.result.cpm = 0; - let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + 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', () => { TRION_BID_RESPONSE.result.ad = null; - let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + let response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); expect(response).to.deep.equal([]); TRION_BID_RESPONSE.result.ad = 'test'; }); @@ -153,7 +153,7 @@ describe('Trion adapter tests', () => { let bidHeight = '2'; TRION_BID_RESPONSE.result.width = bidWidth; TRION_BID_RESPONSE.result.height = bidHeight; - let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + 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'; @@ -163,7 +163,7 @@ describe('Trion adapter tests', () => { it('cpm is properly set and transformed to cents', () => { let bidCpm = 2; TRION_BID_RESPONSE.result.cpm = bidCpm * 100; - let response = spec.interpretResponse(TRION_BID_RESPONSE, {bidRequest: TRION_BID}); + let response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); expect(response[0].cpm).to.equal(bidCpm); TRION_BID_RESPONSE.result.cpm = 100; }); From c734aff0c93c44118946c21528d29224900e21cb Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Fri, 8 Feb 2019 18:38:08 -0500 Subject: [PATCH 07/16] adding safety checks to Trion adapter --- modules/trionBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js index a314a12f871..97f82f57b85 100644 --- a/modules/trionBidAdapter.js +++ b/modules/trionBidAdapter.js @@ -147,7 +147,7 @@ export function setStorageData(key, item) { export function acceptPostMessage(e) { var message = e.data || ''; - if (message.indexOf(BASE_KEY + 'userId') !== 0) { + if (!message.indexOf || !message.split || message.indexOf(BASE_KEY + 'userId') !== 0) { return; } var intT = message.split(BASE_KEY + 'userId=')[1]; From 29320dea5d59d0cd289f510bede042925ce7940e Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Mon, 2 Dec 2019 17:15:57 -0500 Subject: [PATCH 08/16] Sending up to trion endpoint if there is bot traffic or the browser tab is not visible. --- modules/trionBidAdapter.js | 6 ++++++ test/spec/modules/trionBidAdapter_spec.js | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js index 97f82f57b85..3595b709a51 100644 --- a/modules/trionBidAdapter.js +++ b/modules/trionBidAdapter.js @@ -84,6 +84,9 @@ function buildTrionUrlParams(bid) { var re = utils.getBidIdParameter('re', bid.params); var url = utils.getTopWindowUrl(); var sizes = utils.parseSizesInput(bid.sizes).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) { @@ -108,6 +111,9 @@ function buildTrionUrlParams(bid) { 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); // remove the trailing "&" if (trionUrl.lastIndexOf('&') === trionUrl.length - 1) { diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index 805ae70a339..20d0918c6e3 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -119,6 +119,28 @@ describe('Trion adapter tests', function () { expect(bidUrlParams).to.include(utils.getTopWindowUrl()); delete params.re; }); + + it('should send the correct state when there is non human traffic', function () { + window.navigator['__defineGetter__']('webdriver', function () { + return 1; + }); + let bidRequests = spec.buildRequests(TRION_BID_REQUEST); + let bidUrlParams = bidRequests[0].data; + expect(bidUrlParams).to.include('tr_wd=1'); + }); + + it('should send the correct states when the document is not visible', function () { + document['__defineGetter__']('hidden', function () { + return 1; + }); + document['__defineGetter__']('visibilityState', function () { + return 'hidden'; + }); + let bidRequests = spec.buildRequests(TRION_BID_REQUEST); + let bidUrlParams = bidRequests[0].data; + expect(bidUrlParams).to.include('tr_wd=1'); + expect(bidUrlParams).to.include('tr_vs=hidden'); + }); }); describe('interpretResponse', function () { From f0c2028f3af20f081124a7b98949b4f9881f947c Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Mon, 2 Dec 2019 17:22:59 -0500 Subject: [PATCH 09/16] sending the wrong param in the test. --- test/spec/modules/trionBidAdapter_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index 20d0918c6e3..9bb7de99b03 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -138,7 +138,7 @@ describe('Trion adapter tests', function () { }); let bidRequests = spec.buildRequests(TRION_BID_REQUEST); let bidUrlParams = bidRequests[0].data; - expect(bidUrlParams).to.include('tr_wd=1'); + expect(bidUrlParams).to.include('tr_hd=1'); expect(bidUrlParams).to.include('tr_vs=hidden'); }); }); From 3322fd4d747ac08e1a35de8ce62de094905ae62c Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Mon, 9 Dec 2019 12:17:55 -0500 Subject: [PATCH 10/16] Trion test cleanup. returning document and window states to their original form after tests. --- test/spec/modules/trionBidAdapter_spec.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index 9bb7de99b03..c062a6671e6 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -121,15 +121,21 @@ describe('Trion adapter tests', function () { }); it('should send the correct state when there is non human traffic', function () { + let originalWD = window.navigator.webdriver; window.navigator['__defineGetter__']('webdriver', function () { return 1; }); let bidRequests = spec.buildRequests(TRION_BID_REQUEST); let bidUrlParams = bidRequests[0].data; expect(bidUrlParams).to.include('tr_wd=1'); + window.navigator['__defineGetter__']('webdriver', function () { + return originalWD; + }); }); it('should send the correct states when the document is not visible', function () { + let originalHD = document.hidden; + let originalVS = document.visibilityState; document['__defineGetter__']('hidden', function () { return 1; }); @@ -140,6 +146,12 @@ describe('Trion adapter tests', function () { let bidUrlParams = bidRequests[0].data; expect(bidUrlParams).to.include('tr_hd=1'); expect(bidUrlParams).to.include('tr_vs=hidden'); + document['__defineGetter__']('hidden', function () { + return originalHD; + }); + document['__defineGetter__']('visibilityState', function () { + return originalVS; + }); }); }); From 4521bf0cc3b7dad6d28124d8e8919fa8874f4add Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Mon, 9 Dec 2019 14:34:25 -0500 Subject: [PATCH 11/16] Trion test cleanup. using before and after to alter window and document objects in tests. --- test/spec/modules/trionBidAdapter_spec.js | 71 +++++++++++++++-------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index c062a6671e6..63c2b71a31a 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -120,37 +120,58 @@ describe('Trion adapter tests', function () { delete params.re; }); - it('should send the correct state when there is non human traffic', function () { - let originalWD = window.navigator.webdriver; - window.navigator['__defineGetter__']('webdriver', function () { - return 1; + describe('webdriver', function () { + let originalWD; + + beforeEach(function () { + originalWD = window.navigator.webdriver; + window.navigator['__defineGetter__']('webdriver', function () { + return 1; + }); }); - let bidRequests = spec.buildRequests(TRION_BID_REQUEST); - let bidUrlParams = bidRequests[0].data; - expect(bidUrlParams).to.include('tr_wd=1'); - window.navigator['__defineGetter__']('webdriver', function () { - return originalWD; + + afterEach(function () { + window.navigator['__defineGetter__']('webdriver', function () { + return originalWD; + }); }); - }); - it('should send the correct states when the document is not visible', function () { - let originalHD = document.hidden; - let originalVS = document.visibilityState; - document['__defineGetter__']('hidden', function () { - return 1; + it('should send the correct state 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'); }); - document['__defineGetter__']('visibilityState', function () { - return 'hidden'; + }); + + describe('visibility', function () { + let originalHD; + let originalVS; + + beforeEach(function () { + originalHD = document.hidden; + originalVS = document.visibilityState; + document['__defineGetter__']('hidden', function () { + return 1; + }); + document['__defineGetter__']('visibilityState', function () { + return 'hidden'; + }); }); - 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'); - document['__defineGetter__']('hidden', function () { - return originalHD; + + afterEach(function () { + document['__defineGetter__']('hidden', function () { + return originalHD; + }); + document['__defineGetter__']('visibilityState', function () { + return originalVS; + }); }); - document['__defineGetter__']('visibilityState', function () { - return originalVS; + + it('should send the correct states when the document is not 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=hidden'); }); }); }); From d408b9c28ae58b9cff6d68c35129d0109ab4fab9 Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Fri, 13 Dec 2019 18:13:53 -0500 Subject: [PATCH 12/16] re-adding trion adapter to prebid project to stop using deprecated function for page url for 3.0 release --- modules/trionBidAdapter.js | 180 +++++++++++++ test/spec/modules/trionBidAdapter_spec.js | 291 ++++++++++++++++++++++ 2 files changed, 471 insertions(+) create mode 100644 modules/trionBidAdapter.js create mode 100644 test/spec/modules/trionBidAdapter_spec.js diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js new file mode 100644 index 00000000000..ce52096936a --- /dev/null +++ b/modules/trionBidAdapter.js @@ -0,0 +1,180 @@ +import * as utils from '../src/utils'; +import {registerBidder} from '../src/adapters/bidderFactory'; + +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) { + var bidRequests = []; + + for (var i = 0; i < validBidRequests.length; i++) { + var bid = validBidRequests[i]; + + var trionUrlParams = buildTrionUrlParams(bid); + + 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) { + if (syncOptions.iframeEnabled) { + handlePostMessage(); + return [{ + type: 'iframe', + url: getSyncUrl() + }]; + } + } + +}; +registerBidder(spec); + +function getSyncUrl() { + var unParsedPubAndSection = getStorageData(BASE_KEY + 'lps') || ':'; + var pubSectionArray = unParsedPubAndSection.split(':') || []; + var pubId = pubSectionArray[0] || -1; + var sectionId = pubSectionArray[1] || -1; + var url = getPublisherUrl(); + return USER_SYNC_URL + `?p=${pubId}&s=${sectionId}&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) { + var pubId = utils.getBidIdParameter('pubId', bid.params); + var sectionId = utils.getBidIdParameter('sectionId', bid.params); + var re = utils.getBidIdParameter('re', bid.params); + var url = getPublisherUrl(); + var sizes = utils.parseSizesInput(bid.sizes).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, 're', re); + 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); + + // remove the trailing "&" + if (trionUrl.lastIndexOf('&') === trionUrl.length - 1) { + trionUrl = trionUrl.substring(0, trionUrl.length - 1); + } + return trionUrl; +} + +function handlePostMessage() { + try { + if (window.addEventListener) { + window.addEventListener('message', acceptPostMessage); + } + } catch (e) { + } +} + +export function getStorageData(key) { + var item = null; + try { + if (window.localStorage) { + item = window.localStorage.getItem(key); + } + } catch (e) { + } + return item; +} + +export function setStorageData(key, item) { + try { + if (window.localStorage) { + window.localStorage.setItem(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/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js new file mode 100644 index 00000000000..c31d5d7ee66 --- /dev/null +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -0,0 +1,291 @@ +import {expect} from 'chai'; +import * as utils from 'src/utils'; +import {spec, acceptPostMessage, getStorageData, setStorageData} from 'modules/trionBidAdapter'; +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' + }, + adUnitCode: 'adunit-code', + sizes: [[300, 250], [300, 600]], + bidId: 'test-bid-id', + bidRequest: 'test-bid-request' +}; + +const TRION_BID_REQUEST = [TRION_BID]; + +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'); + }); + + it('should call buildRequests with the correct optional params', function () { + let params = TRION_BID_REQUEST[0].params; + params.re = 1; + let bidRequests = spec.buildRequests(TRION_BID_REQUEST); + + let bidUrlParams = bidRequests[0].data; + expect(bidUrlParams).to.include('re=1'); + expect(bidUrlParams).to.include(getPublisherUrl()); + delete params.re; + }); + + describe('webdriver', function () { + let originalWD; + + beforeEach(function () { + originalWD = window.navigator.webdriver; + window.navigator['__defineGetter__']('webdriver', function () { + return 1; + }); + }); + + afterEach(function () { + window.navigator['__defineGetter__']('webdriver', function () { + return originalWD; + }); + }); + + it('should send the correct state 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('visibility', function () { + let originalHD; + let originalVS; + + beforeEach(function () { + originalHD = document.hidden; + originalVS = document.visibilityState; + document['__defineGetter__']('hidden', function () { + return 1; + }); + document['__defineGetter__']('visibilityState', function () { + return 'hidden'; + }); + }); + + afterEach(function () { + document['__defineGetter__']('hidden', function () { + return originalHD; + }); + document['__defineGetter__']('visibilityState', function () { + return originalVS; + }); + }); + + it('should send the correct states when the document is not 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=hidden'); + }); + }); + }); + + 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 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); + }); + }); +}); From abe60af94113a399e764756be3c58d97cd998fc8 Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Mon, 16 Dec 2019 10:18:55 -0500 Subject: [PATCH 13/16] minor formatting change --- test/spec/modules/trionBidAdapter_spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index c31d5d7ee66..d9194f3d87a 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -1,6 +1,7 @@ import {expect} from 'chai'; import * as utils from 'src/utils'; import {spec, acceptPostMessage, getStorageData, setStorageData} from 'modules/trionBidAdapter'; + const CONSTANTS = require('src/constants.json'); const adloader = require('src/adloader'); @@ -35,7 +36,7 @@ const TRION_BID_RESPONSE = { }; -const getPublisherUrl = function() { +const getPublisherUrl = function () { var url = null; try { if (window.top == window) { From a8cd6af07210b8f9af6c5ca574a7760fecc5946d Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Mon, 16 Dec 2019 11:56:04 -0500 Subject: [PATCH 14/16] accept size array from media types banner over the sizes array from pubs. --- modules/trionBidAdapter.js | 7 ++++++- test/spec/modules/trionBidAdapter_spec.js | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js index ce52096936a..f31a460b0fe 100644 --- a/modules/trionBidAdapter.js +++ b/modules/trionBidAdapter.js @@ -100,7 +100,8 @@ function buildTrionUrlParams(bid) { var sectionId = utils.getBidIdParameter('sectionId', bid.params); var re = utils.getBidIdParameter('re', bid.params); var url = getPublisherUrl(); - var sizes = utils.parseSizesInput(bid.sizes).join(','); + 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); @@ -139,6 +140,10 @@ function buildTrionUrlParams(bid) { 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) { diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index d9194f3d87a..dc6bfb14a30 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -14,6 +14,11 @@ const TRION_BID = { pubId: '1', sectionId: '2' }, + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]] + } + }, adUnitCode: 'adunit-code', sizes: [[300, 250], [300, 600]], bidId: 'test-bid-id', From 914150a584864d2e1b996062a6e261c84abfa8d1 Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Wed, 15 Jan 2020 20:07:03 -0500 Subject: [PATCH 15/16] updating trion bid adapter to be us privacy and gdpr compliant --- modules/trionBidAdapter.js | 37 ++++++++++++---- test/spec/modules/trionBidAdapter_spec.js | 52 +++++++++++++++++++++++ 2 files changed, 81 insertions(+), 8 deletions(-) diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js index f31a460b0fe..6d564a66e2d 100644 --- a/modules/trionBidAdapter.js +++ b/modules/trionBidAdapter.js @@ -11,13 +11,13 @@ export const spec = { isBidRequestValid: function (bid) { return !!(bid && bid.params && bid.params.pubId && bid.params.sectionId); }, - buildRequests: function (validBidRequests) { + buildRequests: function (validBidRequests, bidderRequest) { var bidRequests = []; for (var i = 0; i < validBidRequests.length; i++) { var bid = validBidRequests[i]; - var trionUrlParams = buildTrionUrlParams(bid); + var trionUrlParams = buildTrionUrlParams(bid, bidderRequest); bidRequests.push({ method: 'GET', @@ -56,12 +56,12 @@ export const spec = { return bidResponses; }, - getUserSyncs: function getUserSyncs(syncOptions) { + getUserSyncs: function getUserSyncs(syncOptions, serverResponses, gdprConsent, usPrivacy) { if (syncOptions.iframeEnabled) { handlePostMessage(); return [{ type: 'iframe', - url: getSyncUrl() + url: getSyncUrl(gdprConsent, usPrivacy) }]; } } @@ -69,13 +69,23 @@ export const spec = { }; registerBidder(spec); -function getSyncUrl() { +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(); - return USER_SYNC_URL + `?p=${pubId}&s=${sectionId}&u=${url}`; + 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() { @@ -95,7 +105,7 @@ function getPublisherUrl() { return url } -function buildTrionUrlParams(bid) { +function buildTrionUrlParams(bid, bidderRequest) { var pubId = utils.getBidIdParameter('pubId', bid.params); var sectionId = utils.getBidIdParameter('sectionId', bid.params); var re = utils.getBidIdParameter('re', bid.params); @@ -132,7 +142,18 @@ function buildTrionUrlParams(bid) { 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); diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index dc6bfb14a30..88bb286b9f0 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -27,6 +27,13 @@ const TRION_BID = { 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]], @@ -197,6 +204,28 @@ describe('Trion adapter tests', function () { 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; + expect(bidUrlParams).to.include('gdprc=test_gdpr_str'); + 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; + expect(bidUrlParams).to.include('usp=1YYY'); + delete TRION_BIDDER_REQUEST.uspConsent; + }); + }); }); describe('interpretResponse', function () { @@ -275,6 +304,29 @@ describe('Trion adapter tests', function () { expect(syncs[0]).to.deep.equal({type: 'iframe', url: USER_SYNC_URL + syncString}); }); + it('should register trion user script with gdpr params', function () { + var 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 syncString = `?p=${pubId}&s=${sectionId}&gc=test_gdpr_str&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 () { + var uspConsent = '1YYY'; + let syncs = spec.getUserSyncs({iframeEnabled: true}, null, null, uspConsent); + let pageUrl = getPublisherUrl(); + let pubId = 1; + let sectionId = 2; + let syncString = `?p=${pubId}&s=${sectionId}&up=1YYY&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; From cc017f95e148bbf49691251a73223445f67e12a5 Mon Sep 17 00:00:00 2001 From: Mike Groh Date: Wed, 15 Jan 2020 20:27:31 -0500 Subject: [PATCH 16/16] encoding consent strings for test --- test/spec/modules/trionBidAdapter_spec.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index 88bb286b9f0..9a57f79e24f 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -213,7 +213,8 @@ describe('Trion adapter tests', function () { }; let bidRequests = spec.buildRequests(TRION_BID_REQUEST, TRION_BIDDER_REQUEST); let bidUrlParams = bidRequests[0].data; - expect(bidUrlParams).to.include('gdprc=test_gdpr_str'); + 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; }); @@ -222,7 +223,8 @@ describe('Trion adapter tests', function () { TRION_BIDDER_REQUEST.uspConsent = '1YYY'; let bidRequests = spec.buildRequests(TRION_BID_REQUEST, TRION_BIDDER_REQUEST); let bidUrlParams = bidRequests[0].data; - expect(bidUrlParams).to.include('usp=1YYY'); + let uspEncoded = encodeURIComponent(TRION_BIDDER_REQUEST.uspConsent); + expect(bidUrlParams).to.include('usp=' + uspEncoded); delete TRION_BIDDER_REQUEST.uspConsent; }); }); @@ -305,7 +307,7 @@ describe('Trion adapter tests', function () { }); it('should register trion user script with gdpr params', function () { - var gdprConsent = { + let gdprConsent = { consentString: 'test_gdpr_str', gdprApplies: true }; @@ -313,17 +315,19 @@ describe('Trion adapter tests', function () { let pageUrl = getPublisherUrl(); let pubId = 1; let sectionId = 2; - let syncString = `?p=${pubId}&s=${sectionId}&gc=test_gdpr_str&g=1&u=${pageUrl}`; + 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 () { - var uspConsent = '1YYY'; + let uspConsent = '1YYY'; let syncs = spec.getUserSyncs({iframeEnabled: true}, null, null, uspConsent); let pageUrl = getPublisherUrl(); let pubId = 1; let sectionId = 2; - let syncString = `?p=${pubId}&s=${sectionId}&up=1YYY&u=${pageUrl}`; + 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}); });