From 85fd44e1e29939bbda2614553fa9ff787579cdbc Mon Sep 17 00:00:00 2001 From: Harry King-Riches <109534328+harrykingriches@users.noreply.github.com> Date: Wed, 8 May 2024 18:49:47 +0100 Subject: [PATCH] Rubicon Bid Adapter: Provide backwards compatibility for transparency object (#11426) * Provide backwards compatibility for transparency object When the property `transparency.params` gets passed in the `ortb2` object, the Rubicon adapter throws an error. This change will provide backwards compatibility for the `params` property by adding it to the `dsaparams` property. If `params` or `dsaparams` does not exist, the value will be turned into an empty string. The same is done for the `domain` property. This ensures that the Bid Adapter will not error if these properties do not exist. * Refactor RubiconBidAdapter to fix transparency object compatibility * Fix transparency object compatibility in RubiconBidAdapter * Fix transparency object compatibility in RubiconBidAdapter * Refactor dsatransparency check --------- Co-authored-by: Harry King-Riches <109534328+Strife9224@users.noreply.github.com> --- modules/rubiconBidAdapter.js | 18 ++++++- test/spec/modules/rubiconBidAdapter_spec.js | 58 +++++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js index c03065cd5a5..9e47807bdc0 100644 --- a/modules/rubiconBidAdapter.js +++ b/modules/rubiconBidAdapter.js @@ -982,11 +982,25 @@ function applyFPD(bidRequest, mediaType, data) { 'transparency', (transparency) => { if (Array.isArray(transparency) && transparency.length) { data['dsatransparency'] = transparency.reduce((param, transp) => { + // make sure domain is there, otherwise skip entry + const domain = transp.domain || ''; + if (!domain) { + return param; + } + + // make sure dsaParam array is there (try both 'dsaparams' and 'params', but prefer dsaparams) + const dsaParamArray = transp.dsaparams || transp.params; + if (!Array.isArray(dsaParamArray) || dsaParamArray.length === 0) { + return param; + } + + // finally we will add this one, if param has been added already, add our seperator if (param) { param += '~~' } - return param += `${transp.domain}~${transp.dsaparams.join('_')}` - }, '') + + return param += `${domain}~${dsaParamArray.join('_')}`; + }, ''); } } ]) diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js index 55e8909f6c8..494943f9f7d 100644 --- a/test/spec/modules/rubiconBidAdapter_spec.js +++ b/test/spec/modules/rubiconBidAdapter_spec.js @@ -1735,6 +1735,64 @@ describe('the rubicon adapter', function () { } } } + it('should send valid dsaparams but filter out invalid ones', function () { + const ortb2Clone = JSON.parse(JSON.stringify(ortb2)); + ortb2Clone.regs.ext.dsa.transparency = [ + { + domain: 'testdomain.com', + dsaparams: [1], + }, + { + domain: '', + dsaparams: [2], + } + ]; + + const expectedTransparency = 'testdomain.com~1'; + const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({ ...b, ortb2: ortb2Clone })), bidderRequest); + const data = parseQuery(request.data); + + expect(data['dsatransparency']).to.equal(expectedTransparency); + }) + it('should send dsaparams if \"ortb2.regs.ext.dsa.transparancy[0].params\"', function() { + const ortb2Clone = JSON.parse(JSON.stringify(ortb2)); + + ortb2Clone.regs.ext.dsa.transparency = [{ + domain: 'testdomain.com', + dsaparams: [1], + }]; + + const expectedTransparency = 'testdomain.com~1'; + const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({...b, ortb2: ortb2Clone})), bidderRequest); + const data = parseQuery(request.data); + + expect(data['dsatransparency']).to.equal(expectedTransparency); + }) + it('should pass an empty transparency param if \"ortb2.regs.ext.dsa.transparency[0].params\" is empty', function() { + const ortb2Clone = JSON.parse(JSON.stringify(ortb2)); + + ortb2Clone.regs.ext.dsa.transparency = [{ + domain: 'testdomain.com', + params: [], + }]; + + const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({...b, ortb2: ortb2Clone})), bidderRequest); + const data = parseQuery(request.data); + expect(data['dsatransparency']).to.be.undefined + }) + it('should send an empty transparency if \"ortb2.regs.ext.dsa.transparency[0].domain\" is empty', function() { + const ortb2Clone = JSON.parse(JSON.stringify(ortb2)); + + ortb2Clone.regs.ext.dsa.transparency = [{ + domain: '', + dsaparams: [1], + }]; + + const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({...b, ortb2: ortb2Clone})), bidderRequest); + const data = parseQuery(request.data); + + expect(data['dsatransparency']).to.be.undefined + }) it('should send dsa signals if \"ortb2.regs.ext.dsa\"', function() { const expectedTransparency = 'testdomain.com~1~~testdomain2.com~1_2' const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({...b, ortb2})), bidderRequest)