From 6b446e602d300e7bf949259e29ef1ec5b3d0144a Mon Sep 17 00:00:00 2001 From: IQZoneAdx <88879712+IQZoneAdx@users.noreply.github.com> Date: Tue, 28 May 2024 18:22:04 +0300 Subject: [PATCH] IQzone Bid Adapter : update placement to plcmt and move coppa from getConfig (#11562) * add IQZone adapter * add endpointId param * add user sync * added gpp support * added support of transanctionId and eids * updated tests * changed placement to plcmt --- modules/iqzoneBidAdapter.js | 58 ++++++++++++----- test/spec/modules/iqzoneBidAdapter_spec.js | 75 ++++++++++++++++++++-- 2 files changed, 111 insertions(+), 22 deletions(-) diff --git a/modules/iqzoneBidAdapter.js b/modules/iqzoneBidAdapter.js index 52f3be7e4b4..3ce622dba10 100644 --- a/modules/iqzoneBidAdapter.js +++ b/modules/iqzoneBidAdapter.js @@ -1,4 +1,4 @@ -import { isFn, deepAccess, logMessage } from '../src/utils.js'; +import { logMessage, logError, deepAccess } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import { config } from '../src/config.js'; @@ -9,8 +9,7 @@ const AD_URL = 'https://smartssp-us-east.iqzone.com/pbjs'; const SYNC_URL = 'https://cs.smartssp.iqzone.com'; function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency) { + if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { return false; } @@ -27,7 +26,7 @@ function isBidResponseValid(bid) { } function getPlacementReqData(bid) { - const { params, bidId, mediaTypes } = bid; + const { params, bidId, mediaTypes, transactionId, userIdAsEids } = bid; const schain = bid.schain || {}; const { placementId, endpointId } = params; const bidfloor = getBidFloor(bid); @@ -57,7 +56,7 @@ function getPlacementReqData(bid) { placement.mimes = mediaTypes[VIDEO].mimes; placement.protocols = mediaTypes[VIDEO].protocols; placement.startdelay = mediaTypes[VIDEO].startdelay; - placement.placement = mediaTypes[VIDEO].placement; + placement.plcmt = mediaTypes[VIDEO].plcmt; placement.skip = mediaTypes[VIDEO].skip; placement.skipafter = mediaTypes[VIDEO].skipafter; placement.minbitrate = mediaTypes[VIDEO].minbitrate; @@ -71,14 +70,19 @@ function getPlacementReqData(bid) { placement.adFormat = NATIVE; } + if (transactionId) { + placement.ext = placement.ext || {}; + placement.ext.tid = transactionId; + } + + if (userIdAsEids && userIdAsEids.length) { + placement.eids = userIdAsEids; + } + return placement; } function getBidFloor(bid) { - if (!isFn(bid.getFloor)) { - return deepAccess(bid, 'params.bidfloor', 0); - } - try { const bidFloor = bid.getFloor({ currency: 'USD', @@ -86,8 +90,9 @@ function getBidFloor(bid) { size: '*', }); return bidFloor.floor; - } catch (_) { - return 0 + } catch (err) { + logError(err); + return 0; } } @@ -151,12 +156,28 @@ export const spec = { host, page, placements, - coppa: config.getConfig('coppa') === true ? 1 : 0, - ccpa: bidderRequest.uspConsent || undefined, - gdpr: bidderRequest.gdprConsent || undefined, + coppa: deepAccess(bidderRequest, 'ortb2.regs.coppa') ? 1 : 0, tmax: bidderRequest.timeout }; + if (bidderRequest.uspConsent) { + request.ccpa = bidderRequest.uspConsent; + } + + if (bidderRequest.gdprConsent) { + request.gdpr = { + consentString: bidderRequest.gdprConsent.consentString + }; + } + + if (bidderRequest.gppConsent) { + request.gpp = bidderRequest.gppConsent.gppString; + request.gpp_sid = bidderRequest.gppConsent.applicableSections; + } else if (bidderRequest.ortb2?.regs?.gpp) { + request.gpp = bidderRequest.ortb2.regs.gpp; + request.gpp_sid = bidderRequest.ortb2.regs.gpp_sid; + } + const len = validBidRequests.length; for (let i = 0; i < len; i++) { const bid = validBidRequests[i]; @@ -184,9 +205,10 @@ export const spec = { return response; }, - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { + getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) => { let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image'; let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`; + if (gdprConsent && gdprConsent.consentString) { if (typeof gdprConsent.gdprApplies === 'boolean') { syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; @@ -194,10 +216,16 @@ export const spec = { syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`; } } + if (uspConsent && uspConsent.consentString) { syncUrl += `&ccpa_consent=${uspConsent.consentString}`; } + if (gppConsent?.gppString && gppConsent?.applicableSections?.length) { + syncUrl += '&gpp=' + gppConsent.gppString; + syncUrl += '&gpp_sid=' + gppConsent.applicableSections.join(','); + } + const coppa = config.getConfig('coppa') ? 1 : 0; syncUrl += `&coppa=${coppa}`; diff --git a/test/spec/modules/iqzoneBidAdapter_spec.js b/test/spec/modules/iqzoneBidAdapter_spec.js index 2e920d3b769..9d012e526e2 100644 --- a/test/spec/modules/iqzoneBidAdapter_spec.js +++ b/test/spec/modules/iqzoneBidAdapter_spec.js @@ -6,6 +6,16 @@ import { getUniqueIdentifierStr } from '../../../src/utils.js'; const bidder = 'iqzone' describe('IQZoneBidAdapter', function () { + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; const bids = [ { bidId: getUniqueIdentifierStr(), @@ -17,7 +27,8 @@ describe('IQZoneBidAdapter', function () { }, params: { placementId: 'testBanner', - } + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -31,7 +42,8 @@ describe('IQZoneBidAdapter', function () { }, params: { placementId: 'testVideo', - } + }, + userIdAsEids }, { bidId: getUniqueIdentifierStr(), @@ -54,7 +66,8 @@ describe('IQZoneBidAdapter', function () { }, params: { placementId: 'testNative', - } + }, + userIdAsEids } ]; @@ -73,7 +86,9 @@ describe('IQZoneBidAdapter', function () { const bidderRequest = { uspConsent: '1---', - gdprConsent: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + gdprConsent: { + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw' + }, refererInfo: { referer: 'https://test.com' }, @@ -129,7 +144,7 @@ describe('IQZoneBidAdapter', function () { expect(data.host).to.be.a('string'); expect(data.page).to.be.a('string'); expect(data.coppa).to.be.a('number'); - expect(data.gdpr).to.be.a('string'); + expect(data.gdpr).to.be.a('object'); expect(data.ccpa).to.be.a('string'); expect(data.tmax).to.be.a('number'); expect(data.placements).to.have.lengthOf(3); @@ -145,6 +160,7 @@ describe('IQZoneBidAdapter', function () { expect(placement.schain).to.be.an('object'); expect(placement.bidfloor).to.exist.and.to.equal(0); expect(placement.type).to.exist.and.to.equal('publisher'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); if (placement.adFormat === BANNER) { expect(placement.sizes).to.be.an('array'); @@ -170,8 +186,8 @@ describe('IQZoneBidAdapter', function () { serverRequest = spec.buildRequests(bids, bidderRequest); let data = serverRequest.data; expect(data.gdpr).to.exist; - expect(data.gdpr).to.be.a('string'); - expect(data.gdpr).to.equal(bidderRequest.gdprConsent); + expect(data.gdpr).to.be.a('object'); + expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); expect(data.ccpa).to.not.exist; delete bidderRequest.gdprConsent; }); @@ -194,6 +210,38 @@ describe('IQZoneBidAdapter', function () { }); }); + describe('gpp consent', function () { + it('bidderRequest.gppConsent', () => { + bidderRequest.gppConsent = { + gppString: 'abc123', + applicableSections: [8] + }; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + delete bidderRequest.gppConsent; + }) + + it('bidderRequest.ortb2.regs.gpp', () => { + bidderRequest.ortb2 = bidderRequest.ortb2 || {}; + bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {}; + bidderRequest.ortb2.regs.gpp = 'abc123'; + bidderRequest.ortb2.regs.gpp_sid = [8]; + + let serverRequest = spec.buildRequests(bids, bidderRequest); + let data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + bidderRequest.ortb2; + }) + }); + describe('interpretResponse', function () { it('Should interpret banner response', function () { const banner = { @@ -370,6 +418,7 @@ describe('IQZoneBidAdapter', function () { expect(serverResponses).to.be.an('array').that.is.empty; }); }); + describe('getUserSyncs', function() { it('Should return array of objects with proper sync config , include GDPR', function() { const syncData = spec.getUserSyncs({}, {}, { @@ -394,5 +443,17 @@ describe('IQZoneBidAdapter', function () { expect(syncData[0].url).to.be.a('string') expect(syncData[0].url).to.equal('https://cs.smartssp.iqzone.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); + it('Should return array of objects with proper sync config , include GPP', function() { + const syncData = spec.getUserSyncs({}, {}, {}, {}, { + gppString: 'abc123', + applicableSections: [8] + }); + expect(syncData).to.be.an('array').which.is.not.empty; + expect(syncData[0]).to.be.an('object') + expect(syncData[0].type).to.be.a('string') + expect(syncData[0].type).to.equal('image') + expect(syncData[0].url).to.be.a('string') + expect(syncData[0].url).to.equal('https://cs.smartssp.iqzone.com/image?pbjs=1&gpp=abc123&gpp_sid=8&coppa=0') + }); }); });