diff --git a/modules/nexx360BidAdapter.js b/modules/nexx360BidAdapter.js index a59bb635875..0689d3b04ce 100644 --- a/modules/nexx360BidAdapter.js +++ b/modules/nexx360BidAdapter.js @@ -1,17 +1,17 @@ import {ajax} from '../src/ajax.js'; import {config} from '../src/config.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import {BANNER, VIDEO} from '../src/mediaTypes.js'; const BIDDER_CODE = 'nexx360'; -const BIDDER_URL = 'https://fast.nexx360.io/prebid' -const CACHE_URL = 'https://fast.nexx360.io/cache' -const METRICS_TRACKER_URL = 'https://fast.nexx360.io/track-imp' +const BIDDER_URL = 'https://fast.nexx360.io/prebid'; +const CACHE_URL = 'https://fast.nexx360.io/cache'; +const METRICS_TRACKER_URL = 'https://fast.nexx360.io/track-imp'; export const spec = { code: BIDDER_CODE, aliases: ['revenuemaker'], // short code - supportedMediaTypes: [BANNER], + supportedMediaTypes: [BANNER, VIDEO], /** * Determines whether or not the given bid request is valid. * @@ -37,6 +37,7 @@ export const spec = { adUnits.push({ account: adunitValue.params.account, tagId: adunitValue.params.tagId, + videoExt: adunitValue.params.videoExt, label: adunitValue.adUnitCode, bidId: adunitValue.bidId, auctionId: adunitValue.auctionId, @@ -84,13 +85,13 @@ export const spec = { if (serverBody.hasOwnProperty('responses')) { Object.keys(serverBody['responses']).forEach(key => { value = serverBody['responses'][key]; + const url = `${CACHE_URL}?uuid=${value['uuid']}`; bidResponse = { requestId: value['bidId'], cpm: value['cpm'], currency: value['currency'], width: value['width'], height: value['height'], - adUrl: `${CACHE_URL}?uuid=${value['uuid']}`, ttl: value['ttl'], creativeId: value['creativeId'], netRevenue: true, @@ -105,6 +106,21 @@ export const spec = { } */ }; + if (value.type === 'banner') bidResponse.adUrl = url; + if (value.type === 'video') { + const params = { + type: 'prebid', + mediatype: 'video', + ssp: value.bidder, + tag_id: value.tagId, + consent: value.consent, + price: value.cpm, + }; + bidResponse.cpm = value.cpm; + bidResponse.mediaType = 'video'; + bidResponse.vastUrl = url; + bidResponse.vastImpUrl = `${METRICS_TRACKER_URL}?${new URLSearchParams(params).toString()}`; + } bidResponses.push(bidResponse); }); } @@ -133,7 +149,7 @@ export const spec = { */ onBidWon: function(bid) { // fires a pixel to confirm a winning bid - const params = { type: 'prebid' }; + const params = { type: 'prebid', mediatype: 'banner' }; if (bid.hasOwnProperty('nexx360')) { if (bid.nexx360.hasOwnProperty('ssp')) params.ssp = bid.nexx360.ssp; if (bid.nexx360.hasOwnProperty('tagId')) params.tag_id = bid.nexx360.tagId; diff --git a/modules/nexx360BidAdapter.md b/modules/nexx360BidAdapter.md index 882d83cb24e..532d48418b6 100644 --- a/modules/nexx360BidAdapter.md +++ b/modules/nexx360BidAdapter.md @@ -10,9 +10,13 @@ Maintainer: gabriel@nexx360.io Connects to Nexx360 network for bids. -Nexx360 bid adapter supports Banner only for the time being. +To use us as a bidder you must have an account and an active "tagId" on our Nexx360 platform. # Test Parameters + +## Web + +### Display ``` var adUnits = [ // Banner adUnit @@ -33,3 +37,23 @@ var adUnits = [ }, ]; ``` + +### Video Instream +``` + var videoAdUnit = { + code: 'video1', + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'instream' + } + }, + bids: [{ + bidder: 'nexx360', + params: { + account: '1067', + tagId: 'luvxjvgn' + } + }] + }; +``` diff --git a/test/spec/modules/nexx360BidAdapter_spec.js b/test/spec/modules/nexx360BidAdapter_spec.js index 7501391cbfc..3d5b2554cda 100644 --- a/test/spec/modules/nexx360BidAdapter_spec.js +++ b/test/spec/modules/nexx360BidAdapter_spec.js @@ -6,35 +6,62 @@ import * as utils from 'src/utils.js'; import { requestBidsHook } from 'modules/consentManagement.js'; describe('Nexx360 bid adapter tests', function () { - var DEFAULT_PARAMS = [{ - adUnitCode: 'banner-div', - bidId: 'aaaa1234', - auctionId: 'bbbb1234', - transactionId: 'cccc1234', - mediaTypes: { - banner: { - sizes: [ - [300, 250] - ] + const DISPLAY_BID_REQUEST = [{ + 'bidder': 'nexx360', + 'params': { + 'account': '1067', + 'tagId': 'luvxjvgn' + }, + 'userId': { + 'id5id': { + 'uid': 'ID5*hQ5WobYI9Od4u52qpaXVKHhxUa4DsOWRAlvaFajm8gINfI1oVAe3UK59416dT4TqDX1pj4MBJ5TYwir6x3JgBw1-avYHSnmvQDdRMbxmC2sNf3ggIRTbyQBdI1RjvHyeDYCsistnTXF_iKF1nutYeQ2BZ4P5d5muZTG7C2PXVFgNg-18io9dCiSjzJXx93KPDYRiuIwtsGGsp51rojlpFw2Fp_dUkjXl4CAblk58DvwNhobwQ27bnBP8F2-Pcs88DYcvKn4r6dm3Vi7ILttxDQ2IgZ2X44ClgjoWh-vRf6ANis8Z7uL16vO8q0P5C21eDYuc4v_KaZqN-p9YWEeEZQ2OpkbRL7n5NieVJExHM6ANkAlLZhVf2T-1906TAIHKDZFm_xMCa1jJfpBqZB2agw2TjfbK6wMtJeHiZaipSuUNlM_CSH0HVXtfMj9yfzjzDZZnltZQ9lvc4JhXye5AwA2X1f9Dhk8VURTvVdfEUlU', + 'ext': { + 'linkType': 2 + } } }, - bidder: 'nexx360', - params: { - account: '1067', - tagId: 'luvxjvgn' + 'userIdAsEids': [ + { + 'source': 'id5-sync.com', + 'uids': [ + { + 'id': 'ID5*hQ5WobYI9Od4u52qpaXVKHhxUa4DsOWRAlvaFajm8gINfI1oVAe3UK59416dT4TqDX1pj4MBJ5TYwir6x3JgBw1-avYHSnmvQDdRMbxmC2sNf3ggIRTbyQBdI1RjvHyeDYCsistnTXF_iKF1nutYeQ2BZ4P5d5muZTG7C2PXVFgNg-18io9dCiSjzJXx93KPDYRiuIwtsGGsp51rojlpFw2Fp_dUkjXl4CAblk58DvwNhobwQ27bnBP8F2-Pcs88DYcvKn4r6dm3Vi7ILttxDQ2IgZ2X44ClgjoWh-vRf6ANis8Z7uL16vO8q0P5C21eDYuc4v_KaZqN-p9YWEeEZQ2OpkbRL7n5NieVJExHM6ANkAlLZhVf2T-1906TAIHKDZFm_xMCa1jJfpBqZB2agw2TjfbK6wMtJeHiZaipSuUNlM_CSH0HVXtfMj9yfzjzDZZnltZQ9lvc4JhXye5AwA2X1f9Dhk8VURTvVdfEUlU', + 'atype': 1, + 'ext': { + 'linkType': 2 + } + } + ] + } + ], + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 250], [300, 600]] + } }, + 'adUnitCode': 'banner-div', + 'transactionId': '9ad89d90-eb73-41b9-bf5f-7a8e2eecff27', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '4d9e29504f8af6', + 'bidderRequestId': '3423b6bd1a922c', + 'auctionId': '05e0a3a1-9f57-41f6-bbcb-2ba9c9e3d2d5', + 'src': 'client', + 'bidRequestsCount': 1, + 'bidderRequestsCount': 1, + 'bidderWinsCount': 0 }]; - var BID_RESPONSE = {'body': { + const DISPLAY_BID_RESPONSE = {'body': { 'responses': [ { - 'bidId': '49a705a42610a', + 'bidId': '4d9e29504f8af6', 'cpm': 0.437245, 'width': 300, 'height': 250, 'creativeId': '98493581', 'currency': 'EUR', 'netRevenue': true, + 'type': 'banner', 'ttl': 360, 'uuid': 'ce6d1ee3-2a05-4d7c-b97a-9e62097798ec', 'bidder': 'appnexus', @@ -44,6 +71,56 @@ describe('Nexx360 bid adapter tests', function () { ], }}; + const VIDEO_BID_REQUEST = [ + { + 'bidder': 'nexx360', + 'params': { + 'account': '1067', + 'tagId': 'yqsc1tfj' + }, + 'mediaTypes': { + 'video': { + 'context': 'instream', + 'playerSize': [[640, 480]], + 'mimes': ['video/mp4'], + 'protocols': [1, 2, 3, 4, 5, 6], + 'playbackmethod': [2], + 'skip': 1 + } + }, + 'adUnitCode': 'video1', + 'transactionId': '5434c81c-7210-44ae-9014-67c75dee48d0', + 'sizes': [[640, 480]], + 'bidId': '22f90541e576a3', + 'bidderRequestId': '1d4549243f3bfd', + 'auctionId': 'ed21b528-bcab-47e2-8605-ec9b71000c89', + 'src': 'client', + 'bidRequestsCount': 1, + 'bidderRequestsCount': 1, + 'bidderWinsCount': 0 + } + ] + + const VIDEO_BID_RESPONSE = {'body': { + 'responses': [ + { + 'bidId': '2c129e8e01859a', + 'type': 'video', + 'uuid': 'b8e7b2f0-c378-479f-aa4f-4f55d5d7d1d5', + 'cpm': 4.5421, + 'width': 1, + 'height': 1, + 'creativeId': '97517771', + 'currency': 'EUR', + 'netRevenue': true, + 'ttl': 360, + 'bidder': 'appnexus', + 'consent': 1, + 'tagId': 'yqsc1tfj' + } + ] + }}; + const DEFAULT_OPTIONS = { gdprConsent: { gdprApplies: true, @@ -69,22 +146,27 @@ describe('Nexx360 bid adapter tests', function () { }] }, }; - it('Verify build request', function () { - const request = spec.buildRequests(DEFAULT_PARAMS, DEFAULT_OPTIONS); + it('Verify banner build request', function () { + const request = spec.buildRequests(DISPLAY_BID_REQUEST, DEFAULT_OPTIONS); expect(request).to.have.property('url').and.to.equal('https://fast.nexx360.io/prebid'); expect(request).to.have.property('method').and.to.equal('POST'); const requestContent = JSON.parse(request.data); + expect(requestContent.userEids.length).to.be.eql(1); + expect(requestContent.userEids[0]).to.have.property('source').and.to.equal('id5-sync.com'); + expect(requestContent.userEids[0]).to.have.property('uids'); + expect(requestContent.userEids[0].uids[0]).to.have.property('id').and.to.equal('ID5*hQ5WobYI9Od4u52qpaXVKHhxUa4DsOWRAlvaFajm8gINfI1oVAe3UK59416dT4TqDX1pj4MBJ5TYwir6x3JgBw1-avYHSnmvQDdRMbxmC2sNf3ggIRTbyQBdI1RjvHyeDYCsistnTXF_iKF1nutYeQ2BZ4P5d5muZTG7C2PXVFgNg-18io9dCiSjzJXx93KPDYRiuIwtsGGsp51rojlpFw2Fp_dUkjXl4CAblk58DvwNhobwQ27bnBP8F2-Pcs88DYcvKn4r6dm3Vi7ILttxDQ2IgZ2X44ClgjoWh-vRf6ANis8Z7uL16vO8q0P5C21eDYuc4v_KaZqN-p9YWEeEZQ2OpkbRL7n5NieVJExHM6ANkAlLZhVf2T-1906TAIHKDZFm_xMCa1jJfpBqZB2agw2TjfbK6wMtJeHiZaipSuUNlM_CSH0HVXtfMj9yfzjzDZZnltZQ9lvc4JhXye5AwA2X1f9Dhk8VURTvVdfEUlU'); expect(requestContent.adUnits[0]).to.have.property('account').and.to.equal('1067'); expect(requestContent.adUnits[0]).to.have.property('tagId').and.to.equal('luvxjvgn'); expect(requestContent.adUnits[0]).to.have.property('label').and.to.equal('banner-div'); - expect(requestContent.adUnits[0]).to.have.property('bidId').and.to.equal('aaaa1234'); - expect(requestContent.adUnits[0]).to.have.property('auctionId').and.to.equal('bbbb1234'); + expect(requestContent.adUnits[0]).to.have.property('bidId').and.to.equal('4d9e29504f8af6'); + expect(requestContent.adUnits[0]).to.have.property('auctionId').and.to.equal('05e0a3a1-9f57-41f6-bbcb-2ba9c9e3d2d5'); expect(requestContent.adUnits[0]).to.have.property('mediatypes').exist; + expect(requestContent.adUnits[0].mediatypes).to.have.property('banner').exist; }); - it('Verify parse response', function () { - const request = spec.buildRequests(DEFAULT_PARAMS, DEFAULT_OPTIONS); - const response = spec.interpretResponse(BID_RESPONSE, request); + it('Verify banner parse response', function () { + const request = spec.buildRequests(DISPLAY_BID_REQUEST, DEFAULT_OPTIONS); + const response = spec.interpretResponse(DISPLAY_BID_RESPONSE, request); expect(response).to.have.lengthOf(1); const bid = response[0]; expect(bid.cpm).to.equal(0.437245); @@ -95,10 +177,44 @@ describe('Nexx360 bid adapter tests', function () { expect(bid.currency).to.equal('EUR'); expect(bid.netRevenue).to.equal(true); expect(bid.ttl).to.equal(360); - expect(bid.requestId).to.equal('49a705a42610a'); + expect(bid.requestId).to.equal('4d9e29504f8af6'); expect(bid.nexx360).to.exist; expect(bid.nexx360.ssp).to.equal('appnexus'); }); + + it('Verify video build request', function () { + const request = spec.buildRequests(VIDEO_BID_REQUEST, DEFAULT_OPTIONS); + expect(request).to.have.property('url').and.to.equal('https://fast.nexx360.io/prebid'); + expect(request).to.have.property('method').and.to.equal('POST'); + const requestContent = JSON.parse(request.data); + expect(requestContent.adUnits[0]).to.have.property('account').and.to.equal('1067'); + expect(requestContent.adUnits[0]).to.have.property('tagId').and.to.equal('yqsc1tfj'); + expect(requestContent.adUnits[0]).to.have.property('label').and.to.equal('video1'); + expect(requestContent.adUnits[0]).to.have.property('bidId').and.to.equal('22f90541e576a3'); + expect(requestContent.adUnits[0]).to.have.property('auctionId').and.to.equal('ed21b528-bcab-47e2-8605-ec9b71000c89'); + expect(requestContent.adUnits[0]).to.have.property('mediatypes').exist; + expect(requestContent.adUnits[0].mediatypes).to.have.property('video').exist; + }); + + it('Verify video parse response', function () { + const request = spec.buildRequests(VIDEO_BID_REQUEST, DEFAULT_OPTIONS); + const response = spec.interpretResponse(VIDEO_BID_RESPONSE, request); + expect(response).to.have.lengthOf(1); + const bid = response[0]; + expect(bid.cpm).to.equal(4.5421); + expect(bid.vastUrl).to.equal('https://fast.nexx360.io/cache?uuid=b8e7b2f0-c378-479f-aa4f-4f55d5d7d1d5'); + expect(bid.vastImpUrl).to.equal('https://fast.nexx360.io/track-imp?type=prebid&mediatype=video&ssp=appnexus&tag_id=yqsc1tfj&consent=1&price=4.5421'); + expect(bid.width).to.equal(1); + expect(bid.height).to.equal(1); + expect(bid.creativeId).to.equal('97517771'); + expect(bid.currency).to.equal('EUR'); + expect(bid.netRevenue).to.equal(true); + expect(bid.ttl).to.equal(360); + expect(bid.requestId).to.equal('2c129e8e01859a'); + expect(bid.nexx360).to.exist; + expect(bid.nexx360.ssp).to.equal('appnexus'); + }); + it('Verifies bidder code', function () { expect(spec.code).to.equal('nexx360'); }); @@ -108,21 +224,21 @@ describe('Nexx360 bid adapter tests', function () { expect(spec.aliases[0]).to.equal('revenuemaker'); }); it('Verifies if bid request valid', function () { - expect(spec.isBidRequestValid(DEFAULT_PARAMS[0])).to.equal(true); + expect(spec.isBidRequestValid(DISPLAY_BID_REQUEST[0])).to.equal(true); }); it('Verifies bid won', function () { - const request = spec.buildRequests(DEFAULT_PARAMS, DEFAULT_OPTIONS); - const response = spec.interpretResponse(BID_RESPONSE, request); + const request = spec.buildRequests(DISPLAY_BID_REQUEST, DEFAULT_OPTIONS); + const response = spec.interpretResponse(DISPLAY_BID_RESPONSE, request); const won = spec.onBidWon(response[0]); expect(won).to.equal(true); }); it('Verifies user sync without cookie in bid response', function () { - var syncs = spec.getUserSyncs({}, [BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent, DEFAULT_OPTIONS.uspConsent); + var syncs = spec.getUserSyncs({}, [DISPLAY_BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent, DEFAULT_OPTIONS.uspConsent); expect(syncs).to.have.lengthOf(0); }); it('Verifies user sync with cookies in bid response', function () { - BID_RESPONSE.body.cookies = [{'type': 'image', 'url': 'http://www.cookie.sync.org/'}]; - var syncs = spec.getUserSyncs({}, [BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent); + DISPLAY_BID_RESPONSE.body.cookies = [{'type': 'image', 'url': 'http://www.cookie.sync.org/'}]; + var syncs = spec.getUserSyncs({}, [DISPLAY_BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent); expect(syncs).to.have.lengthOf(1); expect(syncs[0]).to.have.property('type').and.to.equal('image'); expect(syncs[0]).to.have.property('url').and.to.equal('http://www.cookie.sync.org/');