From a2c47f5be8f40782f95821cbd42301d855d6f12f Mon Sep 17 00:00:00 2001 From: Alexandru Capatina Date: Tue, 27 Sep 2022 09:43:56 +0300 Subject: [PATCH 1/2] Brightcom: add support for uspConsent, coppa, schain, userIdAsEids, userId --- modules/brightcomBidAdapter.js | 40 +++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/modules/brightcomBidAdapter.js b/modules/brightcomBidAdapter.js index 64b3c3a9fc8..bbe0203772a 100644 --- a/modules/brightcomBidAdapter.js +++ b/modules/brightcomBidAdapter.js @@ -75,6 +75,26 @@ function buildRequests(bidReqs, bidderRequest) { deepSetValue(brightcomBidReq, 'user.ext.consent', bidderRequest.gdprConsent.consentString); } + if (bidderRequest && bidderRequest.uspConsent) { + deepSetValue(brightcomBidReq, 'regs.ext.us_privacy', bidderRequest.uspConsent); + } + + if (config.getConfig('coppa') === true) { + deepSetValue(brightcomBidReq, 'regs.coppa', 1); + } + + if (bidReqs[0] && bidReqs[0].schain) { + deepSetValue(brightcomBidReq, 'source.ext.schain', bidReqs[0].schain) + } + + if (bidReqs[0] && bidReqs[0].userIdAsEids) { + deepSetValue(brightcomBidReq, 'user.ext.eids', bidReqs[0].userIdAsEids || []) + } + + if (bidReqs[0] && bidReqs[0].userId) { + deepSetValue(brightcomBidReq, 'user.ext.ids', bidReqs[0].userId || []) + } + return { method: 'POST', url: URL, @@ -103,7 +123,7 @@ function interpretResponse(serverResponse) { logWarn('Brightcom server returned empty/non-json response: ' + JSON.stringify(serverResponse.body)); return []; } - const { body: {id, seatbid} } = serverResponse; + const {body: {id, seatbid}} = serverResponse; try { const brightcomBidResponses = []; if (id && @@ -164,9 +184,9 @@ function _isViewabilityMeasurable(element) { return !_isIframe() && element !== null; } -function _getViewability(element, topWin, { w, h } = {}) { +function _getViewability(element, topWin, {w, h} = {}) { return getWindowTop().document.visibilityState === 'visible' - ? _getPercentInView(element, topWin, { w, h }) + ? _getPercentInView(element, topWin, {w, h}) : 0; } @@ -182,8 +202,8 @@ function _getMinSize(sizes) { return sizes.reduce((min, size) => size.h * size.w < min.h * min.w ? size : min); } -function _getBoundingBox(element, { w, h } = {}) { - let { width, height, left, top, right, bottom } = element.getBoundingClientRect(); +function _getBoundingBox(element, {w, h} = {}) { + let {width, height, left, top, right, bottom} = element.getBoundingClientRect(); if ((width === 0 || height === 0) && w && h) { width = w; @@ -192,7 +212,7 @@ function _getBoundingBox(element, { w, h } = {}) { bottom = top + h; } - return { width, height, left, top, right, bottom }; + return {width, height, left, top, right, bottom}; } function _getIntersectionOfRects(rects) { @@ -225,16 +245,16 @@ function _getIntersectionOfRects(rects) { return bbox; } -function _getPercentInView(element, topWin, { w, h } = {}) { - const elementBoundingBox = _getBoundingBox(element, { w, h }); +function _getPercentInView(element, topWin, {w, h} = {}) { + const elementBoundingBox = _getBoundingBox(element, {w, h}); // Obtain the intersection of the element and the viewport - const elementInViewBoundingBox = _getIntersectionOfRects([ { + const elementInViewBoundingBox = _getIntersectionOfRects([{ left: 0, top: 0, right: topWin.innerWidth, bottom: topWin.innerHeight - }, elementBoundingBox ]); + }, elementBoundingBox]); let elementInViewArea, elementTotalArea; From 9269f3016a01ae82d8ee724af04b8619069fa954 Mon Sep 17 00:00:00 2001 From: Alexandru Capatina Date: Tue, 4 Oct 2022 19:51:25 +0300 Subject: [PATCH 2/2] Brightcom: tests for updates --- test/spec/modules/brightcomBidAdapter_spec.js | 95 ++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/test/spec/modules/brightcomBidAdapter_spec.js b/test/spec/modules/brightcomBidAdapter_spec.js index 9354544ee5a..1ae73708d00 100644 --- a/test/spec/modules/brightcomBidAdapter_spec.js +++ b/test/spec/modules/brightcomBidAdapter_spec.js @@ -2,6 +2,7 @@ import { expect } from 'chai'; import * as utils from 'src/utils.js'; import { spec } from 'modules/brightcomBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; +import {config} from '../../../src/config'; const URL = 'https://brightcombid.marphezis.com/hb'; @@ -52,7 +53,21 @@ describe('brightcomBidAdapter', function() { }, 'bidId': '5fb26ac22bde4', 'bidderRequestId': '4bf93aeb730cb9', - 'auctionId': 'ffe9a1f7-7b67-4bda-a8e0-9ee5dc9f442e' + 'auctionId': 'ffe9a1f7-7b67-4bda-a8e0-9ee5dc9f442e', + 'schain': { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'exchange1.com', + 'sid': '1234', + 'hp': 1, + 'rid': 'bid-request-1', + 'name': 'publisher', + 'domain': 'publisher.com' + } + ] + }, }]; sandbox = sinon.sandbox.create(); @@ -167,6 +182,84 @@ describe('brightcomBidAdapter', function() { expect(data.user.ext.consent).to.equal(consentString); }); + it('sends us_privacy', function () { + const bidderRequest = { + uspConsent: '1YYY' + }; + const data = JSON.parse(spec.buildRequests(bidRequests, bidderRequest).data) + + expect(data.regs).to.not.equal(null); + expect(data.regs.ext).to.not.equal(null); + expect(data.regs.ext.us_privacy).to.equal('1YYY'); + }); + + it('sends coppa', function () { + sandbox.stub(config, 'getConfig').withArgs('coppa').returns(true); + + const data = JSON.parse(spec.buildRequests(bidRequests).data) + expect(data.regs).to.not.be.undefined; + expect(data.regs.coppa).to.equal(1); + }); + + it('sends schain', function () { + const data = JSON.parse(spec.buildRequests(bidRequests).data); + expect(data).to.not.be.undefined; + expect(data.source).to.not.be.undefined; + expect(data.source.ext).to.not.be.undefined; + expect(data.source.ext.schain).to.not.be.undefined; + expect(data.source.ext.schain.complete).to.equal(1); + expect(data.source.ext.schain.ver).to.equal('1.0'); + expect(data.source.ext.schain.nodes).to.not.be.undefined; + expect(data.source.ext.schain.nodes).to.lengthOf(1); + expect(data.source.ext.schain.nodes[0].asi).to.equal('exchange1.com'); + expect(data.source.ext.schain.nodes[0].sid).to.equal('1234'); + expect(data.source.ext.schain.nodes[0].hp).to.equal(1); + expect(data.source.ext.schain.nodes[0].rid).to.equal('bid-request-1'); + expect(data.source.ext.schain.nodes[0].name).to.equal('publisher'); + expect(data.source.ext.schain.nodes[0].domain).to.equal('publisher.com'); + }); + + it('sends user eid parameters', function () { + bidRequests[0].userIdAsEids = [{ + source: 'pubcid.org', + uids: [{ + id: 'userid_pubcid' + }] + }, { + source: 'adserver.org', + uids: [{ + id: 'userid_ttd', + ext: { + rtiPartner: 'TDID' + } + }] + } + ]; + + const data = JSON.parse(spec.buildRequests(bidRequests).data); + + expect(data.user).to.not.be.undefined; + expect(data.user.ext).to.not.be.undefined; + expect(data.user.ext.eids).to.not.be.undefined; + expect(data.user.ext.eids).to.deep.equal(bidRequests[0].userIdAsEids); + }); + + it('sends user id parameters', function () { + const userId = { + sharedid: { + id: '01*******', + third: '01E*******' + } + }; + + bidRequests[0].userId = userId; + + const data = JSON.parse(spec.buildRequests(bidRequests).data); + expect(data.user).to.not.be.undefined; + expect(data.user.ext).to.not.be.undefined; + expect(data.user.ext.ids).is.deep.equal(userId); + }); + context('when element is fully in view', function() { it('returns 100', function() { Object.assign(element, { width: 600, height: 400 });