From a051204a452172411997d1a78661536c394232b4 Mon Sep 17 00:00:00 2001 From: QuentinGallard Date: Thu, 13 Jun 2024 16:28:17 +0200 Subject: [PATCH] SmileWanted : add schain support --- modules/smilewantedBidAdapter.js | 31 ++++-- .../modules/smilewantedBidAdapter_spec.js | 95 ++++++++++++++++++- 2 files changed, 119 insertions(+), 7 deletions(-) diff --git a/modules/smilewantedBidAdapter.js b/modules/smilewantedBidAdapter.js index 7d4a4bca6157..0604a0c45c9e 100644 --- a/modules/smilewantedBidAdapter.js +++ b/modules/smilewantedBidAdapter.js @@ -52,6 +52,24 @@ export const spec = { return true; }, + /** + * Serialize the supply chain object to a string uri encoded + * + * @param {*} schain object + */ + serializeSupplyChain: function(schain) { + if (!schain?.nodes) return null; + const nodesProperties = ['asi', 'sid', 'hp', 'rid', 'name', 'domain', 'ext']; + + const header = `${schain.ver},${schain.complete}!`; + const nodes = schain.nodes.map(node => nodesProperties.map(prop => + node[prop] ? encodeURIComponent(node[prop]) : '') + .join(',')) + .join('!'); + + return header + nodes; + }, + /** * Make a server request from the list of BidRequests. * @@ -82,7 +100,8 @@ export const spec = { or from mediaTypes.banner.pos */ positionType: bid.params.positionType || '', - prebidVersion: '$prebid.version$' + prebidVersion: '$prebid.version$', + schain: spec.serializeSupplyChain(bid.schain) }; const floor = getBidFloor(bid); @@ -154,16 +173,16 @@ export const spec = { if (response) { const dealId = response.dealId || ''; const bidResponse = { - requestId: bidRequestData.bidId, + ad: response.ad, cpm: response.cpm, - width: response.width, - height: response.height, creativeId: response.creativeId, - dealId: response.dealId, currency: response.currency, + dealId: response.dealId, + height: response.height, netRevenue: response.isNetCpm, + requestId: bidRequestData.bidId, ttl: response.ttl, - ad: response.ad, + width: response.width, }; if (response.formatTypeSw === 'video_instream' || response.formatTypeSw === 'video_outstream') { diff --git a/test/spec/modules/smilewantedBidAdapter_spec.js b/test/spec/modules/smilewantedBidAdapter_spec.js index 99c4034610f5..61a6d3e99a50 100644 --- a/test/spec/modules/smilewantedBidAdapter_spec.js +++ b/test/spec/modules/smilewantedBidAdapter_spec.js @@ -76,6 +76,49 @@ const DISPLAY_REQUEST_WITH_POSITION_TYPE = [{ }, }]; +const SCHAIN = { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'exchange1.com', + 'sid': '1234', + 'hp': 1, + 'rid': 'bid-request-1', + 'name': 'publisher', + 'domain': 'publisher.com' + }, + { + 'asi': 'exchange2.com', + 'sid': 'abcd', + 'hp': 1, + 'rid': 'bid-request-2', + 'name': 'intermediary', + 'domain': 'intermediary.com' + } + ] +}; + +const DISPLAY_REQUEST_WITH_SCHAIN = [{ + adUnitCode: 'sw_300x250', + bidId: '12345', + sizes: [ + [300, 250], + [300, 200] + ], + bidder: 'smilewanted', + params: { + zoneId: 1, + }, + requestId: 'request_abcd1234', + ortb2Imp: { + ext: { + tid: 'trans_abcd1234', + } + }, + schain: SCHAIN, +}]; + const BID_RESPONSE_DISPLAY = { body: { cpm: 3, @@ -580,8 +623,14 @@ describe('smilewantedBidAdapterTests', function () { expect(requestContent).to.have.property('positionType').and.to.equal('infeed'); }); + it('SmileWanted - Verify if schain is well passed', function () { + const request = spec.buildRequests(DISPLAY_REQUEST_WITH_SCHAIN, {}); + const requestContent = JSON.parse(request[0].data); + expect(requestContent).to.have.property('schain').and.to.equal('1.0,1!exchange1.com,1234,1,bid-request-1,publisher,publisher.com!exchange2.com,abcd,1,bid-request-2,intermediary,intermediary.com'); + }); + it('SmileWanted - Verify user sync', function () { - var syncs = spec.getUserSyncs({iframeEnabled: true}, {}, { + let syncs = spec.getUserSyncs({iframeEnabled: true}, {}, { consentString: 'foo' }, '1NYN'); expect(syncs).to.have.lengthOf(1); @@ -599,3 +648,47 @@ describe('smilewantedBidAdapterTests', function () { expect(syncs).to.have.lengthOf(1); }); }); + +describe('Supply Chain Serializer tests', function () { + it('Verify a multi node supply chain serialization matches iab example', function() { + let schain = { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'exchange1.com', + 'sid': '1234', + 'hp': 1, + 'rid': 'bid-request-1', + 'name': 'publisher', + 'domain': 'publisher.com' + }, + { + 'asi': 'exchange2.com', + 'sid': 'abcd', + 'hp': 1, + 'rid': 'bid-request-2', + 'name': 'intermediary', + 'domain': 'intermediary.com' + } + ] + }; + + let serializedSchain = spec.serializeSupplyChain(schain); + expect(serializedSchain).to.equal('1.0,1!exchange1.com,1234,1,bid-request-1,publisher,publisher.com!exchange2.com,abcd,1,bid-request-2,intermediary,intermediary.com'); + }); + + it('Verify that null schain produce null result', function () { + let actual = spec.serializeSupplyChain(null); + expect(actual).to.equal(null); + }); + + it('Verify that schain with null nodes produce null result', function () { + let schain = { + 'ver': '1.0', + 'complete': 1 + }; + let actual = spec.serializeSupplyChain(null); + expect(actual).to.equal(null); + }); +});