From 5b534be06889409d347784179a7ec8821f4fce8f Mon Sep 17 00:00:00 2001 From: Kevin Siow Date: Thu, 11 Jan 2024 10:32:32 +0100 Subject: [PATCH 01/15] Dailymotion Bid Adaptor: initial release --- modules/dailymotionBidAdapter.js | 55 +++++++ modules/dailymotionBidAdapter.md | 73 +++++++++ .../modules/dailymotionBidAdapter_spec.js | 148 ++++++++++++++++++ 3 files changed, 276 insertions(+) create mode 100644 modules/dailymotionBidAdapter.js create mode 100644 modules/dailymotionBidAdapter.md create mode 100644 test/spec/modules/dailymotionBidAdapter_spec.js diff --git a/modules/dailymotionBidAdapter.js b/modules/dailymotionBidAdapter.js new file mode 100644 index 00000000000..fe1c91b9226 --- /dev/null +++ b/modules/dailymotionBidAdapter.js @@ -0,0 +1,55 @@ +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { VIDEO } from '../src/mediaTypes.js'; + +export const spec = { + code: 'dailymotion', + gvlid: 573, + supportedMediaTypes: [VIDEO], + + /** + * Determines whether or not the given bid request is valid. + * The only mandatory parameters for a bid to be valid are the api_key and position configuration entries. + * Other parameters are optional. + * + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: () => { + const dmConfig = config.getConfig('dailymotion'); + return !!(dmConfig?.api_key && dmConfig?.position); + }, + + /** + * Make a server request from the list of valid BidRequests (that already passed the isBidRequestValid call) + * + * @param {BidRequest[]} validBidRequests A non-empty list of valid bid requests that should be sent to the Server. + * @param {BidderRequest} bidderRequest + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: (validBidRequests = [], bidderRequest) => validBidRequests.map(bid => ({ + method: 'POST', + url: 'https://pb.dmxleo.com', + data: { + bidder_request: bidderRequest, + config: config.getConfig('dailymotion'), + coppa: config.getConfig('coppa'), + request: bid, + }, + options: { + withCredentials: true, + crossOrigin: true + }, + })), + + /** + * Map the response from the server into a list of bids. + * As dailymotion prebid server returns an entry with the correct Prebid structure, + * we directly include it as the only bid in the response. + * + * @param {*} serverResponse A successful response from the server. + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: serverResponse => serverResponse?.body ? [serverResponse.body] : [], +}; + +registerBidder(spec); diff --git a/modules/dailymotionBidAdapter.md b/modules/dailymotionBidAdapter.md new file mode 100644 index 00000000000..a54b76f052d --- /dev/null +++ b/modules/dailymotionBidAdapter.md @@ -0,0 +1,73 @@ +# Overview + +``` +Module Name: Dailymotion Bid Adapter +Module Type: Bidder Adapter +Maintainer: ad-leo-engineering@dailymotion.com +``` + +# Description + +Dailymotion prebid adapter. + +# Configuration options + +Before calling this adapter, you need to set its configuration with a call to setConfig like this: + +``` +config.setConfig({ + dailymotion: { + api_key: 'test_api_key', + position: 'test_position', + xid: 'x123456' + } +}); +``` + +This call must be made before each auction. Here's a description of each parameter: +* `api_key` is your publisher API key. For testing purpose, you can use "dailymotion-testing". +* `position` parameter is the ad position in the video and must either be "preroll", "midroll" or "postroll". +* `xid` is the Dailymotion video identifier and should be provided to have better contextual data and higher fillrate. + +# Test Parameters + +By setting the following configuration options, you'll get a constant response to any request to validate your adapter integration: + +``` +config.setConfig({ + dailymotion: { + api_key: 'dailymotion-testing', + position: 'preroll' + } +}); +``` + +Please note that failing to set these configuration options will result in the adapter not bidding at all. + +# Sample video AdUnit + +``` +const adUnits = [ + { + code: 'test-ad-unit', + mediaTypes: { + video: { + context: 'instream', + playerSize: [1280, 720], + }, + }, + bids: [{ + bidder: "dailymotion", + params: {} + }] + } +]; +``` + +# Integrating the adapter + +To use the adapter with any non-test request, you first need to ask an API key from Dailymotion. Please contact us through **DailymotionPrebid.js@dailymotion.com**. + +You will then be able to use it within the `config` before making a bid request. + +This API key will ensure proper identification of your inventory and allow you to get real bids. diff --git a/test/spec/modules/dailymotionBidAdapter_spec.js b/test/spec/modules/dailymotionBidAdapter_spec.js new file mode 100644 index 00000000000..a4452c1dccc --- /dev/null +++ b/test/spec/modules/dailymotionBidAdapter_spec.js @@ -0,0 +1,148 @@ +import { config } from 'src/config.js'; +import { expect } from 'chai'; +import { spec } from 'modules/dailymotionBidAdapter.js'; + +describe('dailymotionBidAdapterTests', () => { + // Validate that isBidRequestValid only validates requests + // with both api_key and position config parameters set + it('validates isBidRequestValid', () => { + config.setConfig({ dailymotion: {} }); + expect(spec.isBidRequestValid({ + bidder: 'dailymotion', + })).to.be.false; + + config.setConfig({ dailymotion: { api_key: 'test_api_key' } }); + expect(spec.isBidRequestValid({ + bidder: 'dailymotion', + })).to.be.false; + + config.setConfig({ dailymotion: { position: 'test_position' } }); + expect(spec.isBidRequestValid({ + bidder: 'dailymotion', + })).to.be.false; + + config.setConfig({ dailymotion: { api_key: 'test_api_key', position: 'test_position' } }); + expect(spec.isBidRequestValid({ + bidder: 'dailymotion', + })).to.be.true; + }); + + // Validate request generation with api key & position only + it('validates buildRequests - with api key & position', () => { + const dmConfig = { api_key: 'test_api_key', position: 'test_position' }; + + config.setConfig({ + dailymotion: dmConfig, + coppa: true, + }); + + const bidRequestData = [{ + adUnitCode: 'test_adunitcode', + auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', + bidId: 123456, + bidder: 'dailymotion', + }]; + + const bidderRequestData = { + uspConsent: '1YN-', + gdprConsent: { + consentString: 'xxx', + gdprApplies: 1 + }, + }; + + const [request] = spec.buildRequests(bidRequestData, bidderRequestData); + const { data: reqData } = request; + + expect(request.url).to.equal('https://pb.dmxleo.com'); + expect(reqData.bidder_request).to.equal(bidderRequestData) + expect(reqData.config).to.equal(dmConfig); + expect(reqData.coppa).to.be.true; + expect(reqData.request).to.equal(bidRequestData[0]); + }); + + // Validate request generation with api key, position, xid + it('validates buildRequests - with auth & xid', function () { + const dmConfig = { + api_key: 'test_api_key', + position: 'test_position', + xid: 'x123456', + }; + + config.setConfig({ dailymotion: dmConfig }); + + const bidRequestData = [{ + adUnitCode: 'test_adunitcode', + auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', + bidId: 123456, + bidder: 'dailymotion', + }]; + + const bidderRequestData = { + uspConsent: '1YN-', + gdprConsent: { + consentString: 'xxx', + gdprApplies: 1 + }, + }; + + const [request] = spec.buildRequests(bidRequestData, bidderRequestData); + const { data: reqData } = request; + + expect(request.url).to.equal('https://pb.dmxleo.com'); + expect(reqData.bidder_request).to.equal(bidderRequestData) + expect(reqData.config).to.equal(dmConfig); + expect(reqData.coppa).to.equal(true); + expect(reqData.request).to.equal(bidRequestData[0]); + }); + + it('validates buildRequests - with empty/undefined validBidRequests', function () { + const dmConfig = { + api_key: 'test_api_key', + position: 'test_position', + xid: 'x123456', + }; + + config.setConfig({ dailymotion: dmConfig }); + + expect(spec.buildRequests([], {})).to.have.lengthOf(0); + + expect(spec.buildRequests(undefined, {})).to.have.lengthOf(0); + }); + + it('validates interpretResponse', function () { + const serverResponse = { + body: { + ad: 'https://fakecacheserver/cache?uuid=1234', + cacheId: '1234', + cpm: 20.0, + creativeId: '5678', + currency: 'USD', + dealId: 'deal123', + nurl: 'https://bid/nurl', + requestId: 'test_requestid', + vastUrl: 'https://fakecacheserver/cache?uuid=1234', + }, + }; + + const bids = spec.interpretResponse(serverResponse); + expect(bids).to.have.lengthOf(1); + + const [bid] = bids; + expect(bid.ad).to.equal(serverResponse.body.ad); + expect(bid.cacheId).to.equal(serverResponse.body.cacheId); + expect(bid.cpm).to.equal(serverResponse.body.cpm); + expect(bid.creativeId).to.equal(serverResponse.body.creativeId); + expect(bid.currency).to.equal(serverResponse.body.currency); + expect(bid.dealId).to.equal(serverResponse.body.dealId); + expect(bid.nurl).to.equal(serverResponse.body.nurl); + expect(bid.requestId).to.equal(serverResponse.body.requestId); + expect(bid.vastUrl).to.equal(serverResponse.body.vastUrl); + }); + + it('validates interpretResponse - with empty/undefined serverResponse', function () { + expect(spec.interpretResponse({})).to.have.lengthOf(0); + + expect(spec.interpretResponse(undefined)).to.have.lengthOf(0); + }); +}); From 807c75bce31223fd872b13bbb19d193ea24a79ff Mon Sep 17 00:00:00 2001 From: Aditi Chaudhary Date: Mon, 22 Jan 2024 17:56:53 +0100 Subject: [PATCH 02/15] .md file lint issue resolved --- modules/dailymotionBidAdapter.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/dailymotionBidAdapter.md b/modules/dailymotionBidAdapter.md index a54b76f052d..7323dfe6d9c 100644 --- a/modules/dailymotionBidAdapter.md +++ b/modules/dailymotionBidAdapter.md @@ -14,7 +14,7 @@ Dailymotion prebid adapter. Before calling this adapter, you need to set its configuration with a call to setConfig like this: -``` +```javascript config.setConfig({ dailymotion: { api_key: 'test_api_key', @@ -25,6 +25,7 @@ config.setConfig({ ``` This call must be made before each auction. Here's a description of each parameter: + * `api_key` is your publisher API key. For testing purpose, you can use "dailymotion-testing". * `position` parameter is the ad position in the video and must either be "preroll", "midroll" or "postroll". * `xid` is the Dailymotion video identifier and should be provided to have better contextual data and higher fillrate. @@ -33,7 +34,7 @@ This call must be made before each auction. Here's a description of each paramet By setting the following configuration options, you'll get a constant response to any request to validate your adapter integration: -``` +```javascript config.setConfig({ dailymotion: { api_key: 'dailymotion-testing', @@ -46,7 +47,7 @@ Please note that failing to set these configuration options will result in the a # Sample video AdUnit -``` +```javascript const adUnits = [ { code: 'test-ad-unit', From 6c25624cbebc2087ca6ad01391eb43662ea39182 Mon Sep 17 00:00:00 2001 From: Kevin Siow Date: Wed, 31 Jan 2024 10:39:24 +0100 Subject: [PATCH 03/15] Dailymotion Bid Adaptor: build bidder request based on param with fallbacks --- modules/dailymotionBidAdapter.js | 24 +++- .../modules/dailymotionBidAdapter_spec.js | 115 ++++++++++++++---- 2 files changed, 110 insertions(+), 29 deletions(-) diff --git a/modules/dailymotionBidAdapter.js b/modules/dailymotionBidAdapter.js index fe1c91b9226..42e3f2a141e 100644 --- a/modules/dailymotionBidAdapter.js +++ b/modules/dailymotionBidAdapter.js @@ -30,10 +30,30 @@ export const spec = { method: 'POST', url: 'https://pb.dmxleo.com', data: { - bidder_request: bidderRequest, + bidder_request: { + gdprConsent: { + apiVersion: bidderRequest?.gdprConsent?.apiVersion || 1, + consentString: bidderRequest?.gdprConsent?.consentString || '', + // Cast boolean in any case (eg: if value is int) to ensure type + gdprApplies: !!bidderRequest?.gdprConsent?.gdprApplies, + }, + refererInfo: { + page: bidderRequest?.refererInfo?.page || '', + }, + uspConsent: bidderRequest?.uspConsent || '', + }, config: config.getConfig('dailymotion'), coppa: config.getConfig('coppa'), - request: bid, + request: { + auctionId: bid.auctionId || '', + bidId: bid.bidId || '', + mediaTypes: { + video: { + playerSize: bid.mediaTypes?.[VIDEO]?.playerSize || [], + }, + }, + sizes: bid.sizes || [], + }, }, options: { withCredentials: true, diff --git a/test/spec/modules/dailymotionBidAdapter_spec.js b/test/spec/modules/dailymotionBidAdapter_spec.js index a4452c1dccc..e333e870d7d 100644 --- a/test/spec/modules/dailymotionBidAdapter_spec.js +++ b/test/spec/modules/dailymotionBidAdapter_spec.js @@ -1,6 +1,7 @@ import { config } from 'src/config.js'; import { expect } from 'chai'; import { spec } from 'modules/dailymotionBidAdapter.js'; +import { VIDEO } from '../../../src/mediaTypes'; describe('dailymotionBidAdapterTests', () => { // Validate that isBidRequestValid only validates requests @@ -37,17 +38,25 @@ describe('dailymotionBidAdapterTests', () => { }); const bidRequestData = [{ - adUnitCode: 'test_adunitcode', auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', bidId: 123456, - bidder: 'dailymotion', + mediaTypes: { + video: { + playerSize: [[1280, 720]], + }, + }, + sizes: [[1920, 1080]], }]; const bidderRequestData = { + refererInfo: { + page: 'https://publisher.com', + }, uspConsent: '1YN-', gdprConsent: { + apiVersion: 2, consentString: 'xxx', - gdprApplies: 1 + gdprApplies: true, }, }; @@ -55,34 +64,44 @@ describe('dailymotionBidAdapterTests', () => { const { data: reqData } = request; expect(request.url).to.equal('https://pb.dmxleo.com'); - expect(reqData.bidder_request).to.equal(bidderRequestData) - expect(reqData.config).to.equal(dmConfig); + + expect(reqData.config).to.eql(dmConfig); expect(reqData.coppa).to.be.true; - expect(reqData.request).to.equal(bidRequestData[0]); + + expect(reqData.bidder_request).to.eql(bidderRequestData) + expect(reqData.request).to.eql(bidRequestData[0]); }); // Validate request generation with api key, position, xid - it('validates buildRequests - with auth & xid', function () { + it('validates buildRequests - with auth & xid', () => { const dmConfig = { api_key: 'test_api_key', position: 'test_position', xid: 'x123456', }; - config.setConfig({ dailymotion: dmConfig }); + config.setConfig({ dailymotion: dmConfig, coppa: undefined }); const bidRequestData = [{ - adUnitCode: 'test_adunitcode', auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', bidId: 123456, - bidder: 'dailymotion', + mediaTypes: { + video: { + playerSize: [[1280, 720]], + }, + }, + sizes: [[1920, 1080]], }]; const bidderRequestData = { + refererInfo: { + page: 'https://publisher.com', + }, uspConsent: '1YN-', gdprConsent: { + apiVersion: 2, consentString: 'xxx', - gdprApplies: 1 + gdprApplies: 1, }, }; @@ -90,13 +109,63 @@ describe('dailymotionBidAdapterTests', () => { const { data: reqData } = request; expect(request.url).to.equal('https://pb.dmxleo.com'); - expect(reqData.bidder_request).to.equal(bidderRequestData) - expect(reqData.config).to.equal(dmConfig); - expect(reqData.coppa).to.equal(true); - expect(reqData.request).to.equal(bidRequestData[0]); + + expect(reqData.config).to.eql(dmConfig); + expect(reqData.coppa).to.be.undefined; + + expect(reqData.bidder_request).to.eql({ + ...bidderRequestData, + gdprConsent: { + ...bidderRequestData.gdprConsent, + gdprApplies: true, // Verify cast to boolean + }, + }); + + expect(reqData.request).to.eql(bidRequestData[0]); + }); + + it('validates buildRequests - with default values on empty bid & bidder request', () => { + const dmConfig = { + api_key: 'test_api_key', + position: 'test_position', + xid: 'x123456', + }; + + config.setConfig({ dailymotion: dmConfig, coppa: false }); + + const [request] = spec.buildRequests([{}], {}); + const { data: reqData } = request; + + expect(request.url).to.equal('https://pb.dmxleo.com'); + + expect(reqData.config).to.eql(dmConfig); + expect(reqData.coppa).to.be.false; + + expect(reqData.bidder_request).to.eql({ + gdprConsent: { + apiVersion: 1, + consentString: '', + gdprApplies: false, + }, + refererInfo: { + page: '', + }, + uspConsent: '', + }); + + expect(reqData.request).to.eql({ + auctionId: '', + bidId: '', + mediaTypes: { + video: { + playerSize: [], + }, + }, + sizes: [], + }); }); - it('validates buildRequests - with empty/undefined validBidRequests', function () { + it('validates buildRequests - with empty/undefined validBidRequests', () => { const dmConfig = { api_key: 'test_api_key', position: 'test_position', @@ -110,7 +179,7 @@ describe('dailymotionBidAdapterTests', () => { expect(spec.buildRequests(undefined, {})).to.have.lengthOf(0); }); - it('validates interpretResponse', function () { + it('validates interpretResponse', () => { const serverResponse = { body: { ad: 'https://fakecacheserver/cache?uuid=1234', @@ -129,18 +198,10 @@ describe('dailymotionBidAdapterTests', () => { expect(bids).to.have.lengthOf(1); const [bid] = bids; - expect(bid.ad).to.equal(serverResponse.body.ad); - expect(bid.cacheId).to.equal(serverResponse.body.cacheId); - expect(bid.cpm).to.equal(serverResponse.body.cpm); - expect(bid.creativeId).to.equal(serverResponse.body.creativeId); - expect(bid.currency).to.equal(serverResponse.body.currency); - expect(bid.dealId).to.equal(serverResponse.body.dealId); - expect(bid.nurl).to.equal(serverResponse.body.nurl); - expect(bid.requestId).to.equal(serverResponse.body.requestId); - expect(bid.vastUrl).to.equal(serverResponse.body.vastUrl); + expect(bid).to.eql(serverResponse.body); }); - it('validates interpretResponse - with empty/undefined serverResponse', function () { + it('validates interpretResponse - with empty/undefined serverResponse', () => { expect(spec.interpretResponse({})).to.have.lengthOf(0); expect(spec.interpretResponse(undefined)).to.have.lengthOf(0); From 9aab2ea8c4d09d4931194441481595a8598f4ed2 Mon Sep 17 00:00:00 2001 From: Aditi Chaudhary Date: Fri, 16 Feb 2024 15:23:06 +0100 Subject: [PATCH 04/15] Dailymotion Bid Adaptor: support video metadata --- modules/dailymotionBidAdapter.js | 38 +++- modules/dailymotionBidAdapter.md | 72 ++++++-- .../modules/dailymotionBidAdapter_spec.js | 170 ++++++++---------- 3 files changed, 168 insertions(+), 112 deletions(-) diff --git a/modules/dailymotionBidAdapter.js b/modules/dailymotionBidAdapter.js index 42e3f2a141e..5cde05c217c 100644 --- a/modules/dailymotionBidAdapter.js +++ b/modules/dailymotionBidAdapter.js @@ -1,6 +1,38 @@ import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { VIDEO } from '../src/mediaTypes.js'; +import { deepAccess } from '../src/utils.js'; + +/** + * Get video metadata from bid request + * + * @param {BidRequest} bidRequest A valid bid requests that should be sent to the Server. + * @return video metadata + */ +function getVideoMetadata(bidRequest) { + const videoAdUnit = deepAccess(bidRequest, 'mediaTypes.video', {}); + const videoBidderParams = deepAccess(bidRequest, 'params.video', {}); + + const videoParams = { + ...videoAdUnit, + ...videoBidderParams, // Bidder Specific overrides + }; + + const videoMetadata = { + description: videoParams.description || '', + duration: videoParams.duration || 0, + iabcat2: videoParams.iabcat2 || '', + id: videoParams.id || '', + lang: videoParams.lang || '', + private: videoParams.private || false, + tags: videoParams.tags || '', + title: videoParams.title || '', + topics: videoParams.topics || '', + xid: videoParams.xid || '', + }; + + return videoMetadata; +} export const spec = { code: 'dailymotion', @@ -16,7 +48,7 @@ export const spec = { */ isBidRequestValid: () => { const dmConfig = config.getConfig('dailymotion'); - return !!(dmConfig?.api_key && dmConfig?.position); + return !!dmConfig?.api_key; }, /** @@ -50,14 +82,16 @@ export const spec = { mediaTypes: { video: { playerSize: bid.mediaTypes?.[VIDEO]?.playerSize || [], + api: bid.mediaTypes?.[VIDEO]?.api || [], }, }, sizes: bid.sizes || [], }, + video_metadata: getVideoMetadata(bid), }, options: { withCredentials: true, - crossOrigin: true + crossOrigin: true, }, })), diff --git a/modules/dailymotionBidAdapter.md b/modules/dailymotionBidAdapter.md index 7323dfe6d9c..2d67ad7f62d 100644 --- a/modules/dailymotionBidAdapter.md +++ b/modules/dailymotionBidAdapter.md @@ -12,34 +12,35 @@ Dailymotion prebid adapter. # Configuration options -Before calling this adapter, you need to set its configuration with a call to setConfig like this: +Before calling this adapter, you need to set its configuration with a call like this: ```javascript -config.setConfig({ - dailymotion: { - api_key: 'test_api_key', - position: 'test_position', - xid: 'x123456' - } +pbjs.setBidderConfig({ + bidders: ["dailymotion"], + config: { + dailymotion: { + api_key: 'fake_api_key', + } + } }); ``` -This call must be made before each auction. Here's a description of each parameter: +This call must be made before the first auction to allow proper authentication with our servers. -* `api_key` is your publisher API key. For testing purpose, you can use "dailymotion-testing". -* `position` parameter is the ad position in the video and must either be "preroll", "midroll" or "postroll". -* `xid` is the Dailymotion video identifier and should be provided to have better contextual data and higher fillrate. +`api_key` is your publisher API key. For testing purpose, you can use "dailymotion-testing". # Test Parameters By setting the following configuration options, you'll get a constant response to any request to validate your adapter integration: ```javascript -config.setConfig({ - dailymotion: { - api_key: 'dailymotion-testing', - position: 'preroll' - } +pbjs.setBidderConfig({ + bidders: ["dailymotion"], + config: { + dailymotion: { + api_key: 'dailymotion-testing' + } + } }); ``` @@ -55,16 +56,53 @@ const adUnits = [ video: { context: 'instream', playerSize: [1280, 720], + api: [2,7], + description: 'this is a video description', + duration: 556, + iabcat2: 'test_cat', + id: '54321', + lang: 'FR', + private: false, + tags: 'tag_1,tag_2,tag_3', + title: 'test video', + topics: 'topic_1, topic_2', + xid: 'x123456' }, }, bids: [{ bidder: "dailymotion", - params: {} + params: { + video: { + description: 'this is a test video description', + duration: 330, + iabcat2: 'test_cat', + id: '54321', + lang: 'FR', + private: false, + tags: 'tag_1,tag_2,tag_3', + title: 'test video', + topics: 'topic_1, topic_2, topic_3', + xid: 'x123456' + } + } }] } ]; ``` +Following video metadata fields can be added in mediaTypes.video or bids.params.video. If a field exists in both places, it will be overridden by bids.params.video. + +* `description` - Video description +* `duration` - Video duration in seconds +* `iabcat2` - Video IAB category +* `id` - Video unique ID in host video infrastructure +* `lang` - ISO 639-1 code for main language used in the video +* `private` - True if video is not publicly available +* `tags` - Tags for the video, comma separated +* `title` - Video title +* `topics` - Main topics for the video, comma separated +* `xid` - Dailymotion video identifier (only applicable if using the Dailymotion player) and allows better targeting + # Integrating the adapter To use the adapter with any non-test request, you first need to ask an API key from Dailymotion. Please contact us through **DailymotionPrebid.js@dailymotion.com**. diff --git a/test/spec/modules/dailymotionBidAdapter_spec.js b/test/spec/modules/dailymotionBidAdapter_spec.js index e333e870d7d..9e5bfb049ef 100644 --- a/test/spec/modules/dailymotionBidAdapter_spec.js +++ b/test/spec/modules/dailymotionBidAdapter_spec.js @@ -4,48 +4,60 @@ import { spec } from 'modules/dailymotionBidAdapter.js'; import { VIDEO } from '../../../src/mediaTypes'; describe('dailymotionBidAdapterTests', () => { - // Validate that isBidRequestValid only validates requests - // with both api_key and position config parameters set + // Validate that isBidRequestValid only validates requests with api_key it('validates isBidRequestValid', () => { - config.setConfig({ dailymotion: {} }); - expect(spec.isBidRequestValid({ - bidder: 'dailymotion', - })).to.be.false; - - config.setConfig({ dailymotion: { api_key: 'test_api_key' } }); - expect(spec.isBidRequestValid({ - bidder: 'dailymotion', - })).to.be.false; - - config.setConfig({ dailymotion: { position: 'test_position' } }); - expect(spec.isBidRequestValid({ - bidder: 'dailymotion', - })).to.be.false; - - config.setConfig({ dailymotion: { api_key: 'test_api_key', position: 'test_position' } }); - expect(spec.isBidRequestValid({ - bidder: 'dailymotion', - })).to.be.true; + config.setBidderConfig({ + bidders: ['dailymotion'], + config: { dailymotion: {} }, + }); + + expect(config.runWithBidder('dailymotion', () => spec.isBidRequestValid())).to.be.false; + + config.setBidderConfig({ + bidders: ['dailymotion'], + config: { dailymotion: { api_key: 'test_api_key' } }, + }); + + expect(config.runWithBidder('dailymotion', () => spec.isBidRequestValid())).to.be.true; }); - // Validate request generation with api key & position only - it('validates buildRequests - with api key & position', () => { - const dmConfig = { api_key: 'test_api_key', position: 'test_position' }; + // Validate request generation + it('validates buildRequests', () => { + const dmConfig = { api_key: 'test_api_key' }; - config.setConfig({ - dailymotion: dmConfig, - coppa: true, + config.setBidderConfig({ + bidders: ['dailymotion'], + config: { dailymotion: dmConfig }, }); + config.setConfig({ coppa: true }); + const bidRequestData = [{ auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', bidId: 123456, mediaTypes: { video: { playerSize: [[1280, 720]], + api: [2, 7], + description: 'this is a test video', + duration: 300, + iabcat2: 'test_cat', + lang: 'ENG', }, }, sizes: [[1920, 1080]], + params: { + video: { + duration: 556, + id: '54321', + lang: 'FR', + private: false, + tags: 'tag_1,tag_2,tag_3', + title: 'test video', + topics: 'topic_1, topic_2', + xid: 'x123456', + }, + }, }]; const bidderRequestData = { @@ -60,80 +72,52 @@ describe('dailymotionBidAdapterTests', () => { }, }; - const [request] = spec.buildRequests(bidRequestData, bidderRequestData); + const [request] = config.runWithBidder( + 'dailymotion', + () => spec.buildRequests(bidRequestData, bidderRequestData), + ); + const { data: reqData } = request; expect(request.url).to.equal('https://pb.dmxleo.com'); expect(reqData.config).to.eql(dmConfig); expect(reqData.coppa).to.be.true; - expect(reqData.bidder_request).to.eql(bidderRequestData) - expect(reqData.request).to.eql(bidRequestData[0]); + expect(reqData.request.auctionId).to.eql(bidRequestData[0].auctionId); + expect(reqData.request.bidId).to.eql(bidRequestData[0].bidId); + expect(reqData.request.mediaTypes.video.api).to.eql(bidRequestData[0].mediaTypes.video.api); + expect(reqData.request.mediaTypes.video.playerSize).to.eql(bidRequestData[0].mediaTypes.video.playerSize); + expect(reqData.video_metadata).to.eql({ + description: bidRequestData[0].mediaTypes.video.description, + iabcat2: bidRequestData[0].mediaTypes.video.iabcat2, + id: bidRequestData[0].params.video.id, + lang: bidRequestData[0].params.video.lang, + private: bidRequestData[0].params.video.private, + tags: bidRequestData[0].params.video.tags, + title: bidRequestData[0].params.video.title, + topics: bidRequestData[0].params.video.topics, + xid: bidRequestData[0].params.video.xid, + // Overriden through bidder params + duration: bidRequestData[0].params.video.duration, + }); }); - // Validate request generation with api key, position, xid - it('validates buildRequests - with auth & xid', () => { - const dmConfig = { - api_key: 'test_api_key', - position: 'test_position', - xid: 'x123456', - }; - - config.setConfig({ dailymotion: dmConfig, coppa: undefined }); - - const bidRequestData = [{ - auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', - bidId: 123456, - mediaTypes: { - video: { - playerSize: [[1280, 720]], - }, - }, - sizes: [[1920, 1080]], - }]; - - const bidderRequestData = { - refererInfo: { - page: 'https://publisher.com', - }, - uspConsent: '1YN-', - gdprConsent: { - apiVersion: 2, - consentString: 'xxx', - gdprApplies: 1, - }, - }; - - const [request] = spec.buildRequests(bidRequestData, bidderRequestData); - const { data: reqData } = request; - - expect(request.url).to.equal('https://pb.dmxleo.com'); - - expect(reqData.config).to.eql(dmConfig); - expect(reqData.coppa).to.be.undefined; + it('validates buildRequests - with default values on empty bid & bidder request', () => { + const dmConfig = { api_key: 'test_api_key' }; - expect(reqData.bidder_request).to.eql({ - ...bidderRequestData, - gdprConsent: { - ...bidderRequestData.gdprConsent, - gdprApplies: true, // Verify cast to boolean - }, + config.setBidderConfig({ + bidders: ['dailymotion'], + config: { dailymotion: dmConfig }, }); - expect(reqData.request).to.eql(bidRequestData[0]); - }); - - it('validates buildRequests - with default values on empty bid & bidder request', () => { - const dmConfig = { - api_key: 'test_api_key', - position: 'test_position', - xid: 'x123456', - }; + config.setConfig({ coppa: false }); - config.setConfig({ dailymotion: dmConfig, coppa: false }); + const [request] = config.runWithBidder( + 'dailymotion', + () => spec.buildRequests([{}], {}), + ); - const [request] = spec.buildRequests([{}], {}); const { data: reqData } = request; expect(request.url).to.equal('https://pb.dmxleo.com'); @@ -159,6 +143,7 @@ describe('dailymotionBidAdapterTests', () => { mediaTypes: { video: { playerSize: [], + api: [], }, }, sizes: [], @@ -166,13 +151,12 @@ describe('dailymotionBidAdapterTests', () => { }); it('validates buildRequests - with empty/undefined validBidRequests', () => { - const dmConfig = { - api_key: 'test_api_key', - position: 'test_position', - xid: 'x123456', - }; + const dmConfig = { api_key: 'test_api_key' }; - config.setConfig({ dailymotion: dmConfig }); + config.setBidderConfig({ + bidders: ['dailymotion'], + config: { dailymotion: dmConfig }, + }); expect(spec.buildRequests([], {})).to.have.lengthOf(0); From 32d6391d9d984feeefc26b6e548ac5d1b7241fcc Mon Sep 17 00:00:00 2001 From: Kevin Siow Date: Tue, 5 Mar 2024 18:43:25 +0100 Subject: [PATCH 05/15] Dailymotion Bid Adaptor: add support for sending adUnitCode --- modules/dailymotionBidAdapter.js | 1 + test/spec/modules/dailymotionBidAdapter_spec.js | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/dailymotionBidAdapter.js b/modules/dailymotionBidAdapter.js index 5cde05c217c..2c0f5340e78 100644 --- a/modules/dailymotionBidAdapter.js +++ b/modules/dailymotionBidAdapter.js @@ -86,6 +86,7 @@ export const spec = { }, }, sizes: bid.sizes || [], + adUnitCode: bid.adUnitCode || '', }, video_metadata: getVideoMetadata(bid), }, diff --git a/test/spec/modules/dailymotionBidAdapter_spec.js b/test/spec/modules/dailymotionBidAdapter_spec.js index 9e5bfb049ef..c296a983f10 100644 --- a/test/spec/modules/dailymotionBidAdapter_spec.js +++ b/test/spec/modules/dailymotionBidAdapter_spec.js @@ -35,6 +35,7 @@ describe('dailymotionBidAdapterTests', () => { const bidRequestData = [{ auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', bidId: 123456, + adUnitCode: 'preroll', mediaTypes: { video: { playerSize: [[1280, 720]], @@ -83,7 +84,7 @@ describe('dailymotionBidAdapterTests', () => { expect(reqData.config).to.eql(dmConfig); expect(reqData.coppa).to.be.true; - expect(reqData.bidder_request).to.eql(bidderRequestData) + expect(reqData.bidder_request).to.eql(bidderRequestData); expect(reqData.request.auctionId).to.eql(bidRequestData[0].auctionId); expect(reqData.request.bidId).to.eql(bidRequestData[0].bidId); expect(reqData.request.mediaTypes.video.api).to.eql(bidRequestData[0].mediaTypes.video.api); @@ -140,6 +141,7 @@ describe('dailymotionBidAdapterTests', () => { expect(reqData.request).to.eql({ auctionId: '', bidId: '', + adUnitCode: '', mediaTypes: { video: { playerSize: [], From ce0536ca2daf0b9cd7748e987a18736c483c71d5 Mon Sep 17 00:00:00 2001 From: Kevin Siow Date: Wed, 6 Mar 2024 14:21:45 +0100 Subject: [PATCH 06/15] Dailymotion Bid Adaptor: add support for sending startDelay --- modules/dailymotionBidAdapter.js | 1 + test/spec/modules/dailymotionBidAdapter_spec.js | 3 +++ 2 files changed, 4 insertions(+) diff --git a/modules/dailymotionBidAdapter.js b/modules/dailymotionBidAdapter.js index 2c0f5340e78..d31a2350733 100644 --- a/modules/dailymotionBidAdapter.js +++ b/modules/dailymotionBidAdapter.js @@ -83,6 +83,7 @@ export const spec = { video: { playerSize: bid.mediaTypes?.[VIDEO]?.playerSize || [], api: bid.mediaTypes?.[VIDEO]?.api || [], + startDelay: bid.mediaTypes?.[VIDEO]?.startdelay || 0, }, }, sizes: bid.sizes || [], diff --git a/test/spec/modules/dailymotionBidAdapter_spec.js b/test/spec/modules/dailymotionBidAdapter_spec.js index c296a983f10..0c3a8b17206 100644 --- a/test/spec/modules/dailymotionBidAdapter_spec.js +++ b/test/spec/modules/dailymotionBidAdapter_spec.js @@ -44,6 +44,7 @@ describe('dailymotionBidAdapterTests', () => { duration: 300, iabcat2: 'test_cat', lang: 'ENG', + startdelay: 0, }, }, sizes: [[1920, 1080]], @@ -89,6 +90,7 @@ describe('dailymotionBidAdapterTests', () => { expect(reqData.request.bidId).to.eql(bidRequestData[0].bidId); expect(reqData.request.mediaTypes.video.api).to.eql(bidRequestData[0].mediaTypes.video.api); expect(reqData.request.mediaTypes.video.playerSize).to.eql(bidRequestData[0].mediaTypes.video.playerSize); + expect(reqData.request.mediaTypes.video.startDelay).to.eql(bidRequestData[0].mediaTypes.video.startdelay); expect(reqData.video_metadata).to.eql({ description: bidRequestData[0].mediaTypes.video.description, iabcat2: bidRequestData[0].mediaTypes.video.iabcat2, @@ -145,6 +147,7 @@ describe('dailymotionBidAdapterTests', () => { mediaTypes: { video: { playerSize: [], + startDelay: 0, api: [], }, }, From 3092928d306094042ab792b79427b35b8b3ffd55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Millet?= Date: Tue, 19 Mar 2024 17:24:01 +0100 Subject: [PATCH 07/15] feat(LEO-528): Allow multiple IAB categories in video metadata The same way as we can have an array of IAB categories level 1 in the ORTB request, this PR introduces an array for the IAB categories level 2. To be forward compatible with level [2.2](https://github.com/InteractiveAdvertisingBureau/Taxonomies/blob/main/Content%20Taxonomies/Content%20Taxonomy%202.2.tsv) and [3.0](https://github.com/InteractiveAdvertisingBureau/Taxonomies/blob/main/Content%20Taxonomies/Content%20Taxonomy%203.0.tsv) specifications, the category IDs should be sent as strings. --- modules/dailymotionBidAdapter.js | 2 +- modules/dailymotionBidAdapter.md | 8 ++++---- test/spec/modules/dailymotionBidAdapter_spec.js | 15 ++++++++++++++- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/modules/dailymotionBidAdapter.js b/modules/dailymotionBidAdapter.js index d31a2350733..78f955219e3 100644 --- a/modules/dailymotionBidAdapter.js +++ b/modules/dailymotionBidAdapter.js @@ -21,7 +21,7 @@ function getVideoMetadata(bidRequest) { const videoMetadata = { description: videoParams.description || '', duration: videoParams.duration || 0, - iabcat2: videoParams.iabcat2 || '', + iabcat2: Array.isArray(videoParams.iabcat2) ? videoParams.iabcat2 : [], id: videoParams.id || '', lang: videoParams.lang || '', private: videoParams.private || false, diff --git a/modules/dailymotionBidAdapter.md b/modules/dailymotionBidAdapter.md index 2d67ad7f62d..24034dedc56 100644 --- a/modules/dailymotionBidAdapter.md +++ b/modules/dailymotionBidAdapter.md @@ -59,7 +59,7 @@ const adUnits = [ api: [2,7], description: 'this is a video description', duration: 556, - iabcat2: 'test_cat', + iabcat2: ['6', '17'], id: '54321', lang: 'FR', private: false, @@ -75,7 +75,7 @@ const adUnits = [ video: { description: 'this is a test video description', duration: 330, - iabcat2: 'test_cat', + iabcat2: ['6', '17'], id: '54321', lang: 'FR', private: false, @@ -94,14 +94,14 @@ Following video metadata fields can be added in mediaTypes.video or bids.params. * `description` - Video description * `duration` - Video duration in seconds -* `iabcat2` - Video IAB category +* `iabcat2` - List of IAB category IDs from the [2.0 taxonomy](https://github.com/InteractiveAdvertisingBureau/Taxonomies/blob/main/Content%20Taxonomies/Content%20Taxonomy%202.0.tsv) * `id` - Video unique ID in host video infrastructure * `lang` - ISO 639-1 code for main language used in the video * `private` - True if video is not publicly available * `tags` - Tags for the video, comma separated * `title` - Video title * `topics` - Main topics for the video, comma separated -* `xid` - Dailymotion video identifier (only applicable if using the Dailymotion player) and allows better targeting +* `xid` - Dailymotion video identifier (only applicable if using the Dailymotion player), allows better targeting # Integrating the adapter diff --git a/test/spec/modules/dailymotionBidAdapter_spec.js b/test/spec/modules/dailymotionBidAdapter_spec.js index 0c3a8b17206..b1fc1143ad3 100644 --- a/test/spec/modules/dailymotionBidAdapter_spec.js +++ b/test/spec/modules/dailymotionBidAdapter_spec.js @@ -42,7 +42,7 @@ describe('dailymotionBidAdapterTests', () => { api: [2, 7], description: 'this is a test video', duration: 300, - iabcat2: 'test_cat', + iabcat2: ['6', '17'], lang: 'ENG', startdelay: 0, }, @@ -153,6 +153,19 @@ describe('dailymotionBidAdapterTests', () => { }, sizes: [], }); + + expect(reqData.video_metadata).to.eql({ + description: '', + duration: 0, + iabcat2: [], + id: '', + lang: '', + private: false, + tags: '', + title: '', + topics: '', + xid: '', + }); }); it('validates buildRequests - with empty/undefined validBidRequests', () => { From 09f8e16c1627574a5561bde61bca245b793c8a6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Millet?= Date: Wed, 27 Mar 2024 10:28:13 +0100 Subject: [PATCH 08/15] Dailymotion bid adapter: Clarify the video metadata to provide in each player context --- modules/dailymotionBidAdapter.md | 44 ++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/modules/dailymotionBidAdapter.md b/modules/dailymotionBidAdapter.md index 24034dedc56..2fe6d4bdce2 100644 --- a/modules/dailymotionBidAdapter.md +++ b/modules/dailymotionBidAdapter.md @@ -48,6 +48,32 @@ Please note that failing to set these configuration options will result in the a # Sample video AdUnit +To allow better targeting, you should provide as much context about the video as possible. +There are two ways of doing this depending on if you're using Dailymotion player or a third party one. + +If you are using the Dailymotion player, you should only provide the video `xid` in your ad unit, example: + +```javascript +const adUnits = [ + { + code: 'test-ad-unit', + mediaTypes: { + video: { + context: 'instream', + playerSize: [1280, 720], + api: [2,7], + xid: 'x123456' + }, + } + } +]; +``` + +This will automatically fetch the most up-to-date information about the video. +If you provide any other metadata in addition to the `xid`, they will be ignored. + +If you are using a third party video player, you should not provide any `xid` and instead fill the following members: + ```javascript const adUnits = [ { @@ -66,23 +92,14 @@ const adUnits = [ tags: 'tag_1,tag_2,tag_3', title: 'test video', topics: 'topic_1, topic_2', - xid: 'x123456' }, }, bids: [{ bidder: "dailymotion", params: { video: { - description: 'this is a test video description', - duration: 330, - iabcat2: ['6', '17'], - id: '54321', - lang: 'FR', - private: false, - tags: 'tag_1,tag_2,tag_3', - title: 'test video', - topics: 'topic_1, topic_2, topic_3', - xid: 'x123456' + description: 'overriden video description', + duration: 330 } } }] @@ -90,7 +107,8 @@ const adUnits = [ ]; ``` -Following video metadata fields can be added in mediaTypes.video or bids.params.video. If a field exists in both places, it will be overridden by bids.params.video. +Each of the following video metadata fields can be added in mediaTypes.video or bids.params.video. +If a field exists in both places, it will be overridden by bids.params.video. * `description` - Video description * `duration` - Video duration in seconds @@ -101,7 +119,7 @@ Following video metadata fields can be added in mediaTypes.video or bids.params. * `tags` - Tags for the video, comma separated * `title` - Video title * `topics` - Main topics for the video, comma separated -* `xid` - Dailymotion video identifier (only applicable if using the Dailymotion player), allows better targeting +* `xid` - Dailymotion video identifier (only applicable if using the Dailymotion player) # Integrating the adapter From 898d8bbf2a487d23a4be9711c3b822297dcee708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Millet?= Date: Wed, 3 Apr 2024 17:58:54 +0200 Subject: [PATCH 09/15] Dailymotion bid adapter: Move API key to bid params --- modules/dailymotionBidAdapter.js | 13 ++--- modules/dailymotionBidAdapter.md | 86 ++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 44 deletions(-) diff --git a/modules/dailymotionBidAdapter.js b/modules/dailymotionBidAdapter.js index 78f955219e3..e7bdabb37c5 100644 --- a/modules/dailymotionBidAdapter.js +++ b/modules/dailymotionBidAdapter.js @@ -41,14 +41,13 @@ export const spec = { /** * Determines whether or not the given bid request is valid. - * The only mandatory parameters for a bid to be valid are the api_key and position configuration entries. + * The only mandatory parameter for a bid to be valid is the API key. * Other parameters are optional. * * @return boolean True if this is a valid bid, and false otherwise. */ - isBidRequestValid: () => { - const dmConfig = config.getConfig('dailymotion'); - return !!dmConfig?.api_key; + isBidRequestValid: function (bid) { + return (typeof bid.params.apiKey !== 'undefined'); }, /** @@ -74,9 +73,12 @@ export const spec = { }, uspConsent: bidderRequest?.uspConsent || '', }, - config: config.getConfig('dailymotion'), + config: { + api_key = bid.params.apiKey + }, coppa: config.getConfig('coppa'), request: { + adUnitCode: bid.adUnitCode || '', auctionId: bid.auctionId || '', bidId: bid.bidId || '', mediaTypes: { @@ -87,7 +89,6 @@ export const spec = { }, }, sizes: bid.sizes || [], - adUnitCode: bid.adUnitCode || '', }, video_metadata: getVideoMetadata(bid), }, diff --git a/modules/dailymotionBidAdapter.md b/modules/dailymotionBidAdapter.md index 2fe6d4bdce2..795273c9229 100644 --- a/modules/dailymotionBidAdapter.md +++ b/modules/dailymotionBidAdapter.md @@ -12,39 +12,41 @@ Dailymotion prebid adapter. # Configuration options -Before calling this adapter, you need to set its configuration with a call like this: +Before calling this adapter, you need to set at least the API key in the bid parameters: ```javascript -pbjs.setBidderConfig({ - bidders: ["dailymotion"], - config: { - dailymotion: { - api_key: 'fake_api_key', - } - } -}); +const adUnits = [ + { + bids: [{ + bidder: 'dailymotion', + params: { + apiKey: 'fake_api_key' + } + }] + } +]; ``` -This call must be made before the first auction to allow proper authentication with our servers. - -`api_key` is your publisher API key. For testing purpose, you can use "dailymotion-testing". +`apiKey` is your publisher API key. For testing purpose, you can use "dailymotion-testing". # Test Parameters -By setting the following configuration options, you'll get a constant response to any request to validate your adapter integration: +By setting the following bid parameters, you'll get a constant response to any request, to validate your adapter integration: ```javascript -pbjs.setBidderConfig({ - bidders: ["dailymotion"], - config: { - dailymotion: { - api_key: 'dailymotion-testing' - } - } -}); +const adUnits = [ + { + bids: [{ + bidder: 'dailymotion', + params: { + apiKey: 'dailymotion-testing' + } + }] + } +]; ``` -Please note that failing to set these configuration options will result in the adapter not bidding at all. +Please note that failing to set these will result in the adapter not bidding at all. # Sample video AdUnit @@ -56,13 +58,20 @@ If you are using the Dailymotion player, you should only provide the video `xid` ```javascript const adUnits = [ { + bids: [{ + bidder: 'dailymotion', + params: { + apiKey: 'dailymotion-testing' + } + }], code: 'test-ad-unit', mediaTypes: { video: { + api: [2, 7], context: 'instream', - playerSize: [1280, 720], - api: [2,7], - xid: 'x123456' + playerSize: [ [1280, 720] ], + startDelay: 0, + xid: 'x123456' // Dailymotion infrastructure unique video ID }, } } @@ -77,32 +86,33 @@ If you are using a third party video player, you should not provide any `xid` an ```javascript const adUnits = [ { + bids: [{ + bidder: 'dailymotion', + params: { + apiKey: 'dailymotion-testing', + video: { + description: 'overriden video description' + } + } + }], code: 'test-ad-unit', mediaTypes: { video: { + api: [2, 7], context: 'instream', - playerSize: [1280, 720], - api: [2,7], description: 'this is a video description', duration: 556, iabcat2: ['6', '17'], id: '54321', lang: 'FR', + playerSize: [ [1280, 720] ], private: false, + startDelay: 0, tags: 'tag_1,tag_2,tag_3', title: 'test video', topics: 'topic_1, topic_2', }, - }, - bids: [{ - bidder: "dailymotion", - params: { - video: { - description: 'overriden video description', - duration: 330 - } - } - }] + } } ]; ``` @@ -125,6 +135,6 @@ If a field exists in both places, it will be overridden by bids.params.video. To use the adapter with any non-test request, you first need to ask an API key from Dailymotion. Please contact us through **DailymotionPrebid.js@dailymotion.com**. -You will then be able to use it within the `config` before making a bid request. +You will then be able to use it within the bid parameters before making a bid request. This API key will ensure proper identification of your inventory and allow you to get real bids. From 673f831629352f3c3fd35d7db585c9afa535c914 Mon Sep 17 00:00:00 2001 From: Kevin Siow Date: Wed, 3 Apr 2024 19:10:59 +0200 Subject: [PATCH 10/15] Dailymotion bid adapter: Verify API key is string Co-authored-by: Rumesh --- modules/dailymotionBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/dailymotionBidAdapter.js b/modules/dailymotionBidAdapter.js index e7bdabb37c5..97d019bd5af 100644 --- a/modules/dailymotionBidAdapter.js +++ b/modules/dailymotionBidAdapter.js @@ -47,7 +47,7 @@ export const spec = { * @return boolean True if this is a valid bid, and false otherwise. */ isBidRequestValid: function (bid) { - return (typeof bid.params.apiKey !== 'undefined'); + return (typeof bid.params.apiKey === 'string'); }, /** From fbd456d2dc817f7c3854703e5854bc55d659a516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Millet?= Date: Thu, 4 Apr 2024 15:01:29 +0200 Subject: [PATCH 11/15] Dailymotion bid adapter: Move API key to bid params (fix tests) --- modules/dailymotionBidAdapter.js | 4 +- .../modules/dailymotionBidAdapter_spec.js | 60 ++++++++----------- 2 files changed, 27 insertions(+), 37 deletions(-) diff --git a/modules/dailymotionBidAdapter.js b/modules/dailymotionBidAdapter.js index 97d019bd5af..b0411ccf2a5 100644 --- a/modules/dailymotionBidAdapter.js +++ b/modules/dailymotionBidAdapter.js @@ -47,7 +47,7 @@ export const spec = { * @return boolean True if this is a valid bid, and false otherwise. */ isBidRequestValid: function (bid) { - return (typeof bid.params.apiKey === 'string'); + return ((typeof bid !== 'undefined') && (typeof bid?.params?.apiKey === 'string') && (bid.params.apiKey.length > 10)); }, /** @@ -74,7 +74,7 @@ export const spec = { uspConsent: bidderRequest?.uspConsent || '', }, config: { - api_key = bid.params.apiKey + api_key: bid.params.apiKey }, coppa: config.getConfig('coppa'), request: { diff --git a/test/spec/modules/dailymotionBidAdapter_spec.js b/test/spec/modules/dailymotionBidAdapter_spec.js index b1fc1143ad3..f96364e7597 100644 --- a/test/spec/modules/dailymotionBidAdapter_spec.js +++ b/test/spec/modules/dailymotionBidAdapter_spec.js @@ -4,32 +4,29 @@ import { spec } from 'modules/dailymotionBidAdapter.js'; import { VIDEO } from '../../../src/mediaTypes'; describe('dailymotionBidAdapterTests', () => { - // Validate that isBidRequestValid only validates requests with api_key + // Validate that isBidRequestValid only validates requests with apiKey it('validates isBidRequestValid', () => { - config.setBidderConfig({ - bidders: ['dailymotion'], - config: { dailymotion: {} }, - }); - expect(config.runWithBidder('dailymotion', () => spec.isBidRequestValid())).to.be.false; - config.setBidderConfig({ - bidders: ['dailymotion'], - config: { dailymotion: { api_key: 'test_api_key' } }, - }); + const bidWithEmptyApi = { + params: { + apiKey: '', + }, + }; - expect(config.runWithBidder('dailymotion', () => spec.isBidRequestValid())).to.be.true; + expect(config.runWithBidder('dailymotion', () => spec.isBidRequestValid(bidWithEmptyApi))).to.be.false; + + const bidWithApi = { + params: { + apiKey: 'test_api_key', + }, + }; + + expect(config.runWithBidder('dailymotion', () => spec.isBidRequestValid(bidWithApi))).to.be.true; }); // Validate request generation it('validates buildRequests', () => { - const dmConfig = { api_key: 'test_api_key' }; - - config.setBidderConfig({ - bidders: ['dailymotion'], - config: { dailymotion: dmConfig }, - }); - config.setConfig({ coppa: true }); const bidRequestData = [{ @@ -49,6 +46,7 @@ describe('dailymotionBidAdapterTests', () => { }, sizes: [[1920, 1080]], params: { + apiKey: 'test_api_key', video: { duration: 556, id: '54321', @@ -83,9 +81,9 @@ describe('dailymotionBidAdapterTests', () => { expect(request.url).to.equal('https://pb.dmxleo.com'); - expect(reqData.config).to.eql(dmConfig); - expect(reqData.coppa).to.be.true; expect(reqData.bidder_request).to.eql(bidderRequestData); + expect(reqData.config.api_key).to.eql(bidRequestData[0].params.apiKey); + expect(reqData.coppa).to.be.true; expect(reqData.request.auctionId).to.eql(bidRequestData[0].auctionId); expect(reqData.request.bidId).to.eql(bidRequestData[0].bidId); expect(reqData.request.mediaTypes.video.api).to.eql(bidRequestData[0].mediaTypes.video.api); @@ -107,25 +105,24 @@ describe('dailymotionBidAdapterTests', () => { }); it('validates buildRequests - with default values on empty bid & bidder request', () => { - const dmConfig = { api_key: 'test_api_key' }; - - config.setBidderConfig({ - bidders: ['dailymotion'], - config: { dailymotion: dmConfig }, - }); + const bidRequestDataWithApi = [{ + params: { + apiKey: 'test_api_key', + }, + }]; config.setConfig({ coppa: false }); const [request] = config.runWithBidder( 'dailymotion', - () => spec.buildRequests([{}], {}), + () => spec.buildRequests(bidRequestDataWithApi, {}), ); const { data: reqData } = request; expect(request.url).to.equal('https://pb.dmxleo.com'); - expect(reqData.config).to.eql(dmConfig); + expect(reqData.config.api_key).to.eql(bidRequestDataWithApi[0].params.apiKey); expect(reqData.coppa).to.be.false; expect(reqData.bidder_request).to.eql({ @@ -169,13 +166,6 @@ describe('dailymotionBidAdapterTests', () => { }); it('validates buildRequests - with empty/undefined validBidRequests', () => { - const dmConfig = { api_key: 'test_api_key' }; - - config.setBidderConfig({ - bidders: ['dailymotion'], - config: { dailymotion: dmConfig }, - }); - expect(spec.buildRequests([], {})).to.have.lengthOf(0); expect(spec.buildRequests(undefined, {})).to.have.lengthOf(0); From cc0c1bc133b66ff6d719b9e952f54ad1861b2350 Mon Sep 17 00:00:00 2001 From: Kevin Siow Date: Thu, 18 Apr 2024 09:27:00 +0200 Subject: [PATCH 12/15] Dailymotion Bid Adaptor: add gpp support and get coppa from request --- modules/dailymotionBidAdapter.js | 12 +- .../modules/dailymotionBidAdapter_spec.js | 115 +++++++++++++++++- 2 files changed, 119 insertions(+), 8 deletions(-) diff --git a/modules/dailymotionBidAdapter.js b/modules/dailymotionBidAdapter.js index b0411ccf2a5..e7a5be56654 100644 --- a/modules/dailymotionBidAdapter.js +++ b/modules/dailymotionBidAdapter.js @@ -1,4 +1,3 @@ -import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { VIDEO } from '../src/mediaTypes.js'; import { deepAccess } from '../src/utils.js'; @@ -47,7 +46,7 @@ export const spec = { * @return boolean True if this is a valid bid, and false otherwise. */ isBidRequestValid: function (bid) { - return ((typeof bid !== 'undefined') && (typeof bid?.params?.apiKey === 'string') && (bid.params.apiKey.length > 10)); + return typeof bid?.params?.apiKey === 'string' && bid.params.apiKey.length > 10; }, /** @@ -72,11 +71,18 @@ export const spec = { page: bidderRequest?.refererInfo?.page || '', }, uspConsent: bidderRequest?.uspConsent || '', + gppConsent: { + gppString: deepAccess(bidderRequest, 'gppConsent.gppString') + || deepAccess(bidderRequest, 'ortb2.regs.gpp', ''), + applicableSections: deepAccess(bidderRequest, 'gppConsent.applicableSections') + || deepAccess(bidderRequest, 'ortb2.regs.gpp_sid', []), + }, }, config: { api_key: bid.params.apiKey }, - coppa: config.getConfig('coppa'), + // Cast boolean in any case (value should be 0 or 1) to ensure type + coppa: !!deepAccess(bidderRequest, 'ortb2.regs.coppa'), request: { adUnitCode: bid.adUnitCode || '', auctionId: bid.auctionId || '', diff --git a/test/spec/modules/dailymotionBidAdapter_spec.js b/test/spec/modules/dailymotionBidAdapter_spec.js index f96364e7597..8057a71755f 100644 --- a/test/spec/modules/dailymotionBidAdapter_spec.js +++ b/test/spec/modules/dailymotionBidAdapter_spec.js @@ -27,8 +27,6 @@ describe('dailymotionBidAdapterTests', () => { // Validate request generation it('validates buildRequests', () => { - config.setConfig({ coppa: true }); - const bidRequestData = [{ auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', bidId: 123456, @@ -70,6 +68,15 @@ describe('dailymotionBidAdapterTests', () => { consentString: 'xxx', gdprApplies: true, }, + gppConsent: { + gppString: 'xxx', + applicableSections: [5], + }, + ortb2: { + regs: { + coppa: 1, + }, + }, }; const [request] = config.runWithBidder( @@ -81,7 +88,12 @@ describe('dailymotionBidAdapterTests', () => { expect(request.url).to.equal('https://pb.dmxleo.com'); - expect(reqData.bidder_request).to.eql(bidderRequestData); + expect(reqData.bidder_request).to.eql({ + refererInfo: bidderRequestData.refererInfo, + uspConsent: bidderRequestData.uspConsent, + gdprConsent: bidderRequestData.gdprConsent, + gppConsent: bidderRequestData.gppConsent, + }); expect(reqData.config.api_key).to.eql(bidRequestData[0].params.apiKey); expect(reqData.coppa).to.be.true; expect(reqData.request.auctionId).to.eql(bidRequestData[0].auctionId); @@ -104,6 +116,97 @@ describe('dailymotionBidAdapterTests', () => { }); }); + it('validates buildRequests with fallback values on ortb2 for gpp', () => { + const bidRequestData = [{ + auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', + bidId: 123456, + adUnitCode: 'preroll', + mediaTypes: { + video: { + playerSize: [[1280, 720]], + api: [2, 7], + description: 'this is a test video', + duration: 300, + iabcat2: ['6', '17'], + lang: 'ENG', + startdelay: 0, + }, + }, + sizes: [[1920, 1080]], + params: { + apiKey: 'test_api_key', + video: { + duration: 556, + id: '54321', + lang: 'FR', + private: false, + tags: 'tag_1,tag_2,tag_3', + title: 'test video', + topics: 'topic_1, topic_2', + xid: 'x123456', + }, + }, + }]; + + const bidderRequestData = { + refererInfo: { + page: 'https://publisher.com', + }, + uspConsent: '1YN-', + gdprConsent: { + apiVersion: 2, + consentString: 'xxx', + gdprApplies: true, + }, + ortb2: { + regs: { + gpp: 'xxx', + gpp_sid: [5], + coppa: 0, + }, + }, + }; + + const [request] = config.runWithBidder( + 'dailymotion', + () => spec.buildRequests(bidRequestData, bidderRequestData), + ); + + const { data: reqData } = request; + + expect(request.url).to.equal('https://pb.dmxleo.com'); + + expect(reqData.bidder_request).to.eql({ + refererInfo: bidderRequestData.refererInfo, + uspConsent: bidderRequestData.uspConsent, + gdprConsent: bidderRequestData.gdprConsent, + gppConsent: { + gppString: bidderRequestData.ortb2.regs.gpp, + applicableSections: bidderRequestData.ortb2.regs.gpp_sid, + }, + }); + expect(reqData.config.api_key).to.eql(bidRequestData[0].params.apiKey); + expect(reqData.coppa).to.be.false; + expect(reqData.request.auctionId).to.eql(bidRequestData[0].auctionId); + expect(reqData.request.bidId).to.eql(bidRequestData[0].bidId); + expect(reqData.request.mediaTypes.video.api).to.eql(bidRequestData[0].mediaTypes.video.api); + expect(reqData.request.mediaTypes.video.playerSize).to.eql(bidRequestData[0].mediaTypes.video.playerSize); + expect(reqData.request.mediaTypes.video.startDelay).to.eql(bidRequestData[0].mediaTypes.video.startdelay); + expect(reqData.video_metadata).to.eql({ + description: bidRequestData[0].mediaTypes.video.description, + iabcat2: bidRequestData[0].mediaTypes.video.iabcat2, + id: bidRequestData[0].params.video.id, + lang: bidRequestData[0].params.video.lang, + private: bidRequestData[0].params.video.private, + tags: bidRequestData[0].params.video.tags, + title: bidRequestData[0].params.video.title, + topics: bidRequestData[0].params.video.topics, + xid: bidRequestData[0].params.video.xid, + // Overriden through bidder params + duration: bidRequestData[0].params.video.duration, + }); + }); + it('validates buildRequests - with default values on empty bid & bidder request', () => { const bidRequestDataWithApi = [{ params: { @@ -111,8 +214,6 @@ describe('dailymotionBidAdapterTests', () => { }, }]; - config.setConfig({ coppa: false }); - const [request] = config.runWithBidder( 'dailymotion', () => spec.buildRequests(bidRequestDataWithApi, {}), @@ -135,6 +236,10 @@ describe('dailymotionBidAdapterTests', () => { page: '', }, uspConsent: '', + gppConsent: { + gppString: '', + applicableSections: [], + }, }); expect(reqData.request).to.eql({ From fa56a41f9789189e9312ba7b840bcd8a59877e94 Mon Sep 17 00:00:00 2001 From: Kevin Siow Date: Thu, 18 Apr 2024 15:03:50 +0200 Subject: [PATCH 13/15] Dailymotion Bid Adaptor: fix lint error --- modules/dailymotionBidAdapter.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/dailymotionBidAdapter.js b/modules/dailymotionBidAdapter.js index e7a5be56654..f22471c3c4f 100644 --- a/modules/dailymotionBidAdapter.js +++ b/modules/dailymotionBidAdapter.js @@ -72,10 +72,10 @@ export const spec = { }, uspConsent: bidderRequest?.uspConsent || '', gppConsent: { - gppString: deepAccess(bidderRequest, 'gppConsent.gppString') - || deepAccess(bidderRequest, 'ortb2.regs.gpp', ''), - applicableSections: deepAccess(bidderRequest, 'gppConsent.applicableSections') - || deepAccess(bidderRequest, 'ortb2.regs.gpp_sid', []), + gppString: deepAccess(bidderRequest, 'gppConsent.gppString') || + deepAccess(bidderRequest, 'ortb2.regs.gpp', ''), + applicableSections: deepAccess(bidderRequest, 'gppConsent.applicableSections') || + deepAccess(bidderRequest, 'ortb2.regs.gpp_sid', []), }, }, config: { From 36637e0c02530c06d8577902b74580e7c03e59d8 Mon Sep 17 00:00:00 2001 From: Kevin Siow Date: Thu, 18 Apr 2024 16:28:45 +0200 Subject: [PATCH 14/15] Dailymotion Bid Adaptor: add iabcat1 and fallback to ortb2 for iabcat2 --- modules/dailymotionBidAdapter.js | 13 ++++++++++--- .../modules/dailymotionBidAdapter_spec.js | 19 ++++++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/modules/dailymotionBidAdapter.js b/modules/dailymotionBidAdapter.js index f22471c3c4f..ff8e52d6d11 100644 --- a/modules/dailymotionBidAdapter.js +++ b/modules/dailymotionBidAdapter.js @@ -8,7 +8,7 @@ import { deepAccess } from '../src/utils.js'; * @param {BidRequest} bidRequest A valid bid requests that should be sent to the Server. * @return video metadata */ -function getVideoMetadata(bidRequest) { +function getVideoMetadata(bidRequest, bidderRequest) { const videoAdUnit = deepAccess(bidRequest, 'mediaTypes.video', {}); const videoBidderParams = deepAccess(bidRequest, 'params.video', {}); @@ -20,7 +20,14 @@ function getVideoMetadata(bidRequest) { const videoMetadata = { description: videoParams.description || '', duration: videoParams.duration || 0, - iabcat2: Array.isArray(videoParams.iabcat2) ? videoParams.iabcat2 : [], + iabcat1: deepAccess(bidderRequest, 'ortb2.site.content.cat', []) + // Only take IAB cats of taxonomy V1 + .filter(cat => cat.toLowerCase().indexOf('iab-') === 0), + iabcat2: Array.isArray(videoParams.iabcat2) + ? videoParams.iabcat2 + // Only take IAB cats of taxonomy V2 or higher by excluding "IAB-" type categories + : deepAccess(bidderRequest, 'ortb2.site.content.cat', []) + .filter(cat => cat.toLowerCase().indexOf('iab-') !== 0), id: videoParams.id || '', lang: videoParams.lang || '', private: videoParams.private || false, @@ -96,7 +103,7 @@ export const spec = { }, sizes: bid.sizes || [], }, - video_metadata: getVideoMetadata(bid), + video_metadata: getVideoMetadata(bid, bidderRequest), }, options: { withCredentials: true, diff --git a/test/spec/modules/dailymotionBidAdapter_spec.js b/test/spec/modules/dailymotionBidAdapter_spec.js index 8057a71755f..e5a20fa6b6e 100644 --- a/test/spec/modules/dailymotionBidAdapter_spec.js +++ b/test/spec/modules/dailymotionBidAdapter_spec.js @@ -76,6 +76,11 @@ describe('dailymotionBidAdapterTests', () => { regs: { coppa: 1, }, + site: { + content: { + cat: ['IAB-1', '200'], + }, + }, }, }; @@ -103,6 +108,7 @@ describe('dailymotionBidAdapterTests', () => { expect(reqData.request.mediaTypes.video.startDelay).to.eql(bidRequestData[0].mediaTypes.video.startdelay); expect(reqData.video_metadata).to.eql({ description: bidRequestData[0].mediaTypes.video.description, + iabcat1: ['IAB-1'], // Taxonomy v2 or higher is excluded iabcat2: bidRequestData[0].mediaTypes.video.iabcat2, id: bidRequestData[0].params.video.id, lang: bidRequestData[0].params.video.lang, @@ -116,7 +122,7 @@ describe('dailymotionBidAdapterTests', () => { }); }); - it('validates buildRequests with fallback values on ortb2 for gpp', () => { + it('validates buildRequests with fallback values on ortb2 for gpp & iabcat', () => { const bidRequestData = [{ auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', bidId: 123456, @@ -127,7 +133,6 @@ describe('dailymotionBidAdapterTests', () => { api: [2, 7], description: 'this is a test video', duration: 300, - iabcat2: ['6', '17'], lang: 'ENG', startdelay: 0, }, @@ -164,6 +169,11 @@ describe('dailymotionBidAdapterTests', () => { gpp_sid: [5], coppa: 0, }, + site: { + content: { + cat: ['6', '17'], + }, + }, }, }; @@ -194,7 +204,9 @@ describe('dailymotionBidAdapterTests', () => { expect(reqData.request.mediaTypes.video.startDelay).to.eql(bidRequestData[0].mediaTypes.video.startdelay); expect(reqData.video_metadata).to.eql({ description: bidRequestData[0].mediaTypes.video.description, - iabcat2: bidRequestData[0].mediaTypes.video.iabcat2, + // No iabcat1 here because nothing matches taxonomy + iabcat1: [], + iabcat2: bidderRequestData.ortb2.site.content.cat, id: bidRequestData[0].params.video.id, lang: bidRequestData[0].params.video.lang, private: bidRequestData[0].params.video.private, @@ -259,6 +271,7 @@ describe('dailymotionBidAdapterTests', () => { expect(reqData.video_metadata).to.eql({ description: '', duration: 0, + iabcat1: [], iabcat2: [], id: '', lang: '', From 50dda1fefe3db16212c8177346dd0251740b1a9f Mon Sep 17 00:00:00 2001 From: Kevin Siow Date: Thu, 18 Apr 2024 16:55:46 +0200 Subject: [PATCH 15/15] Dailymotion Bid Adaptor: get iabcats from ortb2.site.content.data --- modules/dailymotionBidAdapter.js | 26 +++++++-- .../modules/dailymotionBidAdapter_spec.js | 56 ++++++++++++++++++- 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/modules/dailymotionBidAdapter.js b/modules/dailymotionBidAdapter.js index ff8e52d6d11..2be5edad78e 100644 --- a/modules/dailymotionBidAdapter.js +++ b/modules/dailymotionBidAdapter.js @@ -17,17 +17,31 @@ function getVideoMetadata(bidRequest, bidderRequest) { ...videoBidderParams, // Bidder Specific overrides }; + // Store as object keys to ensure uniqueness + const iabcat1 = {}; + const iabcat2 = {}; + + deepAccess(bidderRequest, 'ortb2.site.content.data', []).forEach((data) => { + if ([4, 5, 6, 7].includes(data?.ext?.segtax)) { + (Array.isArray(data.segment) ? data.segment : []).forEach((segment) => { + if (typeof segment.id === 'string') { + // See https://docs.prebid.org/features/firstPartyData.html#segments-and-taxonomy + // Only take IAB cats of taxonomy V1 + if (data.ext.segtax === 4) iabcat1[segment.id] = 1; + // Only take IAB cats of taxonomy V2 or higher + if ([5, 6, 7].includes(data.ext.segtax)) iabcat2[segment.id] = 1; + } + }); + } + }); + const videoMetadata = { description: videoParams.description || '', duration: videoParams.duration || 0, - iabcat1: deepAccess(bidderRequest, 'ortb2.site.content.cat', []) - // Only take IAB cats of taxonomy V1 - .filter(cat => cat.toLowerCase().indexOf('iab-') === 0), + iabcat1: Object.keys(iabcat1), iabcat2: Array.isArray(videoParams.iabcat2) ? videoParams.iabcat2 - // Only take IAB cats of taxonomy V2 or higher by excluding "IAB-" type categories - : deepAccess(bidderRequest, 'ortb2.site.content.cat', []) - .filter(cat => cat.toLowerCase().indexOf('iab-') !== 0), + : Object.keys(iabcat2), id: videoParams.id || '', lang: videoParams.lang || '', private: videoParams.private || false, diff --git a/test/spec/modules/dailymotionBidAdapter_spec.js b/test/spec/modules/dailymotionBidAdapter_spec.js index e5a20fa6b6e..a102c26dca2 100644 --- a/test/spec/modules/dailymotionBidAdapter_spec.js +++ b/test/spec/modules/dailymotionBidAdapter_spec.js @@ -78,7 +78,18 @@ describe('dailymotionBidAdapterTests', () => { }, site: { content: { - cat: ['IAB-1', '200'], + data: [ + { + name: 'dataprovider.com', + ext: { segtax: 4 }, + segment: [{ id: 'IAB-1' }], + }, + { + name: 'dataprovider.com', + ext: { segtax: 5 }, + segment: [{ id: '200' }], + }, + ], }, }, }, @@ -171,7 +182,46 @@ describe('dailymotionBidAdapterTests', () => { }, site: { content: { - cat: ['6', '17'], + data: [ + undefined, // Undefined to check proper handling of edge cases + {}, // Empty object to check proper handling of edge cases + { ext: {} }, // Empty ext to check proper handling of edge cases + { + name: 'dataprovider.com', + ext: { segtax: 22 }, // Invalid segtax to check proper handling of edge cases + segment: [{ id: '400' }], + }, + { + name: 'dataprovider.com', + ext: { segtax: 5 }, + segment: undefined, // Invalid segment to check proper handling of edge cases + }, + { + name: 'dataprovider.com', + ext: { segtax: 4 }, + segment: undefined, // Invalid segment to check proper handling of edge cases + }, + { + name: 'dataprovider.com', + ext: { segtax: 4 }, + segment: [{ id: 2222 }], // Invalid segment id to check proper handling of edge cases + }, + { + name: 'dataprovider.com', + ext: { segtax: 5 }, + segment: [{ id: '6' }], + }, + { + name: 'dataprovider.com', + ext: { segtax: 5 }, + segment: [{ id: '6' }], // Check that same cat won't be duplicated + }, + { + name: 'dataprovider.com', + ext: { segtax: 5 }, + segment: [{ id: '17' }, { id: '20' }], + }, + ], }, }, }, @@ -206,7 +256,7 @@ describe('dailymotionBidAdapterTests', () => { description: bidRequestData[0].mediaTypes.video.description, // No iabcat1 here because nothing matches taxonomy iabcat1: [], - iabcat2: bidderRequestData.ortb2.site.content.cat, + iabcat2: ['6', '17', '20'], id: bidRequestData[0].params.video.id, lang: bidRequestData[0].params.video.lang, private: bidRequestData[0].params.video.private,