From 0eba11e360324c2c41a3373db548890f91437370 Mon Sep 17 00:00:00 2001 From: Reda Guermas Date: Wed, 4 Mar 2020 15:39:35 -0800 Subject: [PATCH 1/5] Enable supplyChain support --- modules/nobidBidAdapter.js | 11 +++++- test/spec/modules/nobidBidAdapter_spec.js | 47 ++++++++++++++++++++++- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/modules/nobidBidAdapter.js b/modules/nobidBidAdapter.js index cce79efead0..8cb8885549d 100644 --- a/modules/nobidBidAdapter.js +++ b/modules/nobidBidAdapter.js @@ -2,7 +2,7 @@ import * as utils from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'nobid'; -window.nobidVersion = '1.2.1'; +window.nobidVersion = '1.2.3'; window.nobid = window.nobid || {}; window.nobid.bidResponses = window.nobid.bidResponses || {}; window.nobid.timeoutTotal = 0; @@ -57,6 +57,12 @@ function nobidBuildRequests(bids, bidderRequest) { } return uspConsent; } + var schain = function(bids) { + if (bids && bids.length>0) { + return bids[0].schain + } + return null; + } var topLocation = function(bidderRequest) { var ret = ''; if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { @@ -99,6 +105,7 @@ function nobidBuildRequests(bids, bidderRequest) { state['ref'] = document.referrer; state['gdpr'] = gdprConsent(bidderRequest); state['usp'] = uspConsent(bidderRequest); + state['schain'] = schain(bids); return state; } function newAdunit(adunitObject, adunits) { @@ -269,7 +276,7 @@ export const spec = { var buildEndpoint = function() { return resolveEndpoint() + 'adreq?cb=' + Math.floor(Math.random() * 11000); } - log('buildRequests', validBidRequests); + log('validBidRequests', validBidRequests); if (!validBidRequests || validBidRequests.length <= 0) { log('Empty validBidRequests'); return; diff --git a/test/spec/modules/nobidBidAdapter_spec.js b/test/spec/modules/nobidBidAdapter_spec.js index 0005f35523e..91c398b48ad 100644 --- a/test/spec/modules/nobidBidAdapter_spec.js +++ b/test/spec/modules/nobidBidAdapter_spec.js @@ -70,7 +70,7 @@ describe('Nobid Adapter', function () { refererInfo: {referer: REFERER} } - it('should add source and verison to the tag', function () { + it('should add source and version to the tag', function () { const request = spec.buildRequests(bidRequests, bidderRequest); const payload = JSON.parse(request.data); expect(payload.sid).to.equal(SITE_ID); @@ -281,6 +281,51 @@ describe('Nobid Adapter', function () { }); }); + describe('buildRequestsWithSupplyChain', function () { + const SITE_ID = 2; + let bidRequests = [ + { + bidder: 'nobid', + params: { + siteId: SITE_ID + }, + adUnitCode: 'adunit-code', + sizes: [[300, 250]], + bidId: '30b31c1838de1e', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475', + schain: { + validation: 'strict', + config: { + ver: '1.0', + complete: 1, + nodes: [ + { + asi: 'indirectseller.com', + sid: '00001', + name: 'name.com', + hp: 1 + } + ] + } + } + } + ]; + + it('schain exist', function () { + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.schain).to.exist; + expect(payload.schain.validation).to.exist.and.to.equal('strict'); + expect(payload.schain.config.ver).to.exist.and.to.equal('1.0'); + expect(payload.schain.config.complete).to.exist.and.to.equal(1); + expect(payload.schain.config.nodes[0].asi).to.exist.and.to.equal('indirectseller.com'); + expect(payload.schain.config.nodes[0].sid).to.exist.and.to.equal('00001'); + expect(payload.schain.config.nodes[0].name).to.exist.and.to.equal('name.com'); + expect(payload.schain.config.nodes[0].hp).to.exist.and.to.equal(1); + }); + }); + describe('interpretResponseWithUserLimit', function () { const CREATIVE_ID_300x250 = 'CREATIVE-100'; const ADUNIT_300x250 = 'ADUNIT-1'; From c0fb8ee705b3525b386684ebd6484278eb08a003 Mon Sep 17 00:00:00 2001 From: Reda Guermas Date: Wed, 4 Mar 2020 20:10:10 -0800 Subject: [PATCH 2/5] Added support for COPPA --- modules/nobidBidAdapter.js | 19 ++++++++++++++++--- test/spec/modules/nobidBidAdapter_spec.js | 13 +++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/modules/nobidBidAdapter.js b/modules/nobidBidAdapter.js index 8cb8885549d..7fca2d10534 100644 --- a/modules/nobidBidAdapter.js +++ b/modules/nobidBidAdapter.js @@ -1,4 +1,5 @@ import * as utils from '../src/utils.js'; +import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'nobid'; @@ -58,11 +59,20 @@ function nobidBuildRequests(bids, bidderRequest) { return uspConsent; } var schain = function(bids) { - if (bids && bids.length>0) { + if (bids && bids.length > 0) { return bids[0].schain } return null; - } + } + var coppa = function() { + if (config.getConfig('coppa') === true) { + return {'coppa': true}; + } + if (bids && bids.length > 0) { + return bids[0].coppa + } + return null; + } var topLocation = function(bidderRequest) { var ret = ''; if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { @@ -105,7 +115,10 @@ function nobidBuildRequests(bids, bidderRequest) { state['ref'] = document.referrer; state['gdpr'] = gdprConsent(bidderRequest); state['usp'] = uspConsent(bidderRequest); - state['schain'] = schain(bids); + const sch = schain(bids); + if (sch) state['schain'] = sch; + const cop = coppa(); + if (cop) state['coppa'] = cop; return state; } function newAdunit(adunitObject, adunits) { diff --git a/test/spec/modules/nobidBidAdapter_spec.js b/test/spec/modules/nobidBidAdapter_spec.js index 91c398b48ad..8d119461d6a 100644 --- a/test/spec/modules/nobidBidAdapter_spec.js +++ b/test/spec/modules/nobidBidAdapter_spec.js @@ -2,6 +2,7 @@ import { expect } from 'chai'; import * as utils from 'src/utils.js'; import { spec } from 'modules/nobidBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; +import * as bidderFactory from 'src/adapters/bidderFactory.js'; describe('Nobid Adapter', function () { const adapter = newBidder(spec); @@ -294,6 +295,7 @@ describe('Nobid Adapter', function () { bidId: '30b31c1838de1e', bidderRequestId: '22edbae2733bf6', auctionId: '1d1a030790a475', + coppa: true, schain: { validation: 'strict', config: { @@ -323,6 +325,10 @@ describe('Nobid Adapter', function () { expect(payload.schain.config.nodes[0].sid).to.exist.and.to.equal('00001'); expect(payload.schain.config.nodes[0].name).to.exist.and.to.equal('name.com'); expect(payload.schain.config.nodes[0].hp).to.exist.and.to.equal(1); + expect(payload.coppa).to.exist; + expect(payload.coppa).to.exist.and.to.be.true; + expect(payload.a).to.be.lengthOf(1); + expect(request.method).to.equal('POST'); }); }); @@ -404,6 +410,13 @@ describe('Nobid Adapter', function () { expect(pixel.length).to.equal(0); }); + it('should get correct user sync when !iframeEnabled and pixelEnabled', function () { + let pixel = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{body: {syncs: ['sync_url']}}]) + expect(pixel.length).to.equal(1); + expect(pixel[0].type).to.equal('image'); + expect(pixel[0].url).to.equal('sync_url'); + }); + it('should get correct user sync when !iframeEnabled', function () { let pixel = spec.getUserSyncs({}) expect(pixel.length).to.equal(0); From 7013d142bac02ea2a63aabe030cda306a7da7a52 Mon Sep 17 00:00:00 2001 From: Reda Guermas Date: Tue, 18 Aug 2020 17:18:17 -0700 Subject: [PATCH 3/5] Added support for TCF 2.0 --- modules/nobidBidAdapter.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/modules/nobidBidAdapter.js b/modules/nobidBidAdapter.js index f1a9092e31d..0f05b98131e 100644 --- a/modules/nobidBidAdapter.js +++ b/modules/nobidBidAdapter.js @@ -24,6 +24,15 @@ function nobidSetCookie(cname, cvalue, hours) { function nobidGetCookie(cname) { return storage.getCookie(cname); } +function nobidHasPurpose1Consent(bidderRequest) { + let result = true; + if (bidderRequest && bidderRequest.gdprConsent) { + if (bidderRequest.gdprConsent.gdprApplies && bidderRequest.gdprConsent.apiVersion === 2) { + result = !!(utils.deepAccess(bidderRequest.gdprConsent, 'vendorData.purpose.consents.1') === true); + } + } + return result; +} function nobidBuildRequests(bids, bidderRequest) { var serializeState = function(divIds, siteId, adunits) { var filterAdUnitsByIds = function(divIds, adUnits) { @@ -358,11 +367,18 @@ export const spec = { window.nobid.refreshCount++; const payloadString = JSON.stringify(payload).replace(/'|&|#/g, '') const endpoint = buildEndpoint(); + + let options = {}; + if (!nobidHasPurpose1Consent(bidderRequest)) { + options = { withCredentials: false }; + } + return { method: 'POST', url: endpoint, data: payloadString, - bidderRequest + bidderRequest, + options }; }, /** From bfcdfcab9dfd2bc0c3bc9b6136fcf26367e0844c Mon Sep 17 00:00:00 2001 From: Reda Guermas Date: Wed, 16 Sep 2020 19:11:38 -0700 Subject: [PATCH 4/5] Fixed the test coverage. --- modules/nobidBidAdapter.js | 16 +---- test/spec/modules/nobidBidAdapter_spec.js | 71 ++++++++++++++++++++++- 2 files changed, 72 insertions(+), 15 deletions(-) diff --git a/modules/nobidBidAdapter.js b/modules/nobidBidAdapter.js index 0f05b98131e..c2208629aea 100644 --- a/modules/nobidBidAdapter.js +++ b/modules/nobidBidAdapter.js @@ -6,7 +6,7 @@ import { getStorageManager } from '../src/storageManager.js'; const storage = getStorageManager(); const BIDDER_CODE = 'nobid'; -window.nobidVersion = '1.2.6'; +window.nobidVersion = '1.2.8'; window.nobid = window.nobid || {}; window.nobid.bidResponses = window.nobid.bidResponses || {}; window.nobid.timeoutTotal = 0; @@ -305,19 +305,7 @@ window.addEventListener('message', function (event) { if (window.nobid && window.nobid.bidResponses) { var bid = window.nobid.bidResponses['' + adId]; if (bid && bid.adm2) { - var markup = null; - if (bid.is_combo && bid.adm_combo) { - for (var i in bid.adm_combo) { - var combo = bid.adm_combo[i]; - if (!combo.done) { - markup = combo.adm; - combo.done = true; - break; - } - } - } else { - markup = bid.adm2; - } + var markup = bid.adm2; if (markup) { event.source.postMessage('nbTagRenderer.renderAdInSafeFrame|' + markup, '*'); } diff --git a/test/spec/modules/nobidBidAdapter_spec.js b/test/spec/modules/nobidBidAdapter_spec.js index 3b8fd32160b..346356e7d5b 100644 --- a/test/spec/modules/nobidBidAdapter_spec.js +++ b/test/spec/modules/nobidBidAdapter_spec.js @@ -118,7 +118,7 @@ describe('Nobid Adapter', function () { expect(payload.a).to.exist; expect(payload.t).to.exist; expect(payload.tz).to.exist; - expect(payload.r).to.exist; + expect(payload.r).to.exist.and.to.equal('100x100'); expect(payload.lang).to.exist; expect(payload.ref).to.exist; expect(payload.a[0].d).to.exist.and.to.equal('adunit-code'); @@ -264,6 +264,38 @@ describe('Nobid Adapter', function () { expect(payload.gdpr).to.exist; }); + it('sends bid request to ad size', function () { + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.a).to.exist; + expect(payload.a.length).to.exist.and.to.equal(1); + expect(payload.a[0].z[0][0]).to.equal(300); + expect(payload.a[0].z[0][1]).to.equal(250); + }); + + it('sends bid request to div id', function () { + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.a).to.exist; + expect(payload.a[0].d).to.equal('adunit-code'); + }); + + it('sends bid request to site id', function () { + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.a).to.exist; + expect(payload.a[0].sid).to.equal(2); + expect(payload.a[0].at).to.equal('banner'); + expect(payload.a[0].params.siteId).to.equal(2); + }); + + it('sends bid request to ad type', function () { + const request = spec.buildRequests(bidRequests); + const payload = JSON.parse(request.data); + expect(payload.a).to.exist; + expect(payload.a[0].at).to.equal('banner'); + }); + it('sends bid request to ENDPOINT via POST', function () { const request = spec.buildRequests(bidRequests); expect(request.url).to.contain('ads.servenobid.com/adreq'); @@ -291,6 +323,43 @@ describe('Nobid Adapter', function () { expect(payload.gdpr.consentString).to.exist.and.to.equal(consentString); expect(payload.gdpr.consentRequired).to.exist.and.to.be.true; }); + + it('should add gdpr consent information to the request', function () { + let bidderRequest = { + 'bidderCode': 'nobid', + 'auctionId': '1d1a030790a475', + 'bidderRequestId': '22edbae2733bf6', + 'timeout': 3000, + 'gdprConsent': { + gdprApplies: false + } + }; + bidderRequest.bids = bidRequests; + + const request = spec.buildRequests(bidRequests, bidderRequest); + const payload = JSON.parse(request.data); + + expect(payload.gdpr).to.exist; + expect(payload.gdpr.consentString).to.not.exist; + expect(payload.gdpr.consentRequired).to.exist.and.to.be.false; + }); + + it('should add usp consent information to the request', function () { + let bidderRequest = { + 'bidderCode': 'nobid', + 'auctionId': '1d1a030790a475', + 'bidderRequestId': '22edbae2733bf6', + 'timeout': 3000, + 'uspConsent': '1Y-N' + }; + bidderRequest.bids = bidRequests; + + const request = spec.buildRequests(bidRequests, bidderRequest); + const payload = JSON.parse(request.data); + + expect(payload.usp).to.exist; + expect(payload.usp).to.exist.and.to.equal('1Y-N'); + }); }); describe('buildRequestsRefreshCount', function () { From ce07b4d43a746573d896f19575cab85bc849b933 Mon Sep 17 00:00:00 2001 From: Reda Guermas Date: Wed, 16 Sep 2020 19:40:48 -0700 Subject: [PATCH 5/5] Fixed lint issue. --- modules/nobidBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nobidBidAdapter.js b/modules/nobidBidAdapter.js index c2208629aea..00cb14dc01d 100644 --- a/modules/nobidBidAdapter.js +++ b/modules/nobidBidAdapter.js @@ -305,7 +305,7 @@ window.addEventListener('message', function (event) { if (window.nobid && window.nobid.bidResponses) { var bid = window.nobid.bidResponses['' + adId]; if (bid && bid.adm2) { - var markup = bid.adm2; + var markup = bid.adm2; if (markup) { event.source.postMessage('nbTagRenderer.renderAdInSafeFrame|' + markup, '*'); }