From 7fc2b34b2504d4bcce4b248db3f93c4bdbdc214f Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Thu, 23 Nov 2023 02:19:11 +0300 Subject: [PATCH 01/18] added support for gpp consent string --- modules/nextMillenniumBidAdapter.js | 63 +++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index 0cbe954175c..ff4c3ee28b4 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -1,7 +1,8 @@ import { _each, createTrackPixelHtml, - deepAccess, getBidIdParameter, + deepAccess, + getBidIdParameter, getDefinedParams, getWindowTop, isArray, @@ -27,9 +28,17 @@ const SYNC_ENDPOINT = 'https://cookies.nextmillmedia.com/sync?'; const REPORT_ENDPOINT = 'https://report2.hb.brainlyads.com/statistics/metric'; const TIME_TO_LIVE = 360; const VIDEO_PARAMS = [ - 'api', 'linearity', 'maxduration', 'mimes', 'minduration', 'placement', - 'playbackmethod', 'protocols', 'startdelay' + 'api', + 'linearity', + 'maxduration', + 'mimes', + 'minduration', + 'placement', + 'playbackmethod', + 'protocols', + 'startdelay', ]; + const GVLID = 1060; const sendingDataStatistic = initSendingDataStatistic(); @@ -118,16 +127,23 @@ export const spec = { postBody.imp.push(imp); - const gdprConsent = bidderRequest && bidderRequest.gdprConsent; - const uspConsent = bidderRequest && bidderRequest.uspConsent; + const gdprConsent = bidderRequest?.gdprConsent; + const uspConsent = bidderRequest?.uspConsent; + let gppConsent = bidderRequest?.gppConsent?.gppString && bidderRequest?.gppConsent; + if (!gppConsent && bidderRequest?.ortb2?.regs?.gpp) gppConsent = bidderRequest?.ortb2?.regs; - if (gdprConsent || uspConsent) { + if (gdprConsent || uspConsent || gppConsent) { postBody.regs = { ext: {} }; if (uspConsent) { postBody.regs.ext.us_privacy = uspConsent; }; + if (gppConsent) { + postBody.regs.gpp = gppConsent?.gppString || gppConsent?.gpp; + postBody.regs.gpp_sid = bidderRequest.gppConsent?.applicableSections || gppConsent?.gpp_sid; + }; + if (gdprConsent) { if (typeof gdprConsent.gdprApplies !== 'undefined') { postBody.regs.ext.gdpr = gdprConsent.gdprApplies ? 1 : 0; @@ -173,6 +189,7 @@ export const spec = { const params = bidRequest.params; const auctionId = bidRequest.auctionId; const wurl = deepAccess(bid, 'ext.prebid.events.win'); + // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781 addWurl({auctionId, requestId, wurl}); @@ -210,7 +227,7 @@ export const spec = { return bidResponses; }, - getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) { + getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent, gppConsent) { const pixels = []; if (isArray(responses)) { @@ -219,7 +236,7 @@ export const spec = { deepAccess(response, 'body.ext.sync.image', []).forEach(imgUrl => { pixels.push({ type: 'image', - url: replaceUsersyncMacros(imgUrl, gdprConsent, uspConsent) + url: replaceUsersyncMacros(imgUrl, gdprConsent, uspConsent, gppConsent) }); }) } @@ -228,20 +245,29 @@ export const spec = { deepAccess(response, 'body.ext.sync.iframe', []).forEach(iframeUrl => { pixels.push({ type: 'iframe', - url: replaceUsersyncMacros(iframeUrl, gdprConsent, uspConsent) + url: replaceUsersyncMacros(iframeUrl, gdprConsent, uspConsent, gppConsent) }); }) } }) } - if (!pixels.length) { - let syncUrl = SYNC_ENDPOINT; - if (gdprConsent && gdprConsent.gdprApplies) syncUrl += 'gdpr=1&gdpr_consent=' + gdprConsent.consentString + '&'; - if (uspConsent) syncUrl += 'us_privacy=' + uspConsent + '&'; - if (syncOptions.iframeEnabled) pixels.push({type: 'iframe', url: syncUrl + 'type=iframe'}); - if (syncOptions.pixelEnabled) pixels.push({type: 'image', url: syncUrl + 'type=image'}); + if (!pixels.length && (syncOptions.iframeEnabled || syncOptions.pixelEnabled)) { + const syncUrlQuery = []; + if (gdprConsent?.gdprApplies) syncUrlQuery.push('gdpr=1&gdpr_consent=' + gdprConsent.consentString); + if (uspConsent) syncUrlQuery.push('us_privacy=' + uspConsent); + if (gppConsent?.gppString && gppConsent?.applicableSections?.length) { + syncUrlQuery.push('gpp=' + gppConsent.gppString + '&gpp_sid=' + gppConsent?.applicableSections?.join(',')); + } + + const type = syncOptions.iframeEnabled && 'iframe' || 'image'; + syncUrlQuery.push('type=' + type); + pixels.push({ + type, + url: SYNC_ENDPOINT + syncUrlQuery.join('&'), + }); } + return pixels; }, @@ -281,7 +307,7 @@ export const spec = { }, }; -function replaceUsersyncMacros(url, gdprConsent, uspConsent) { +function replaceUsersyncMacros(url, gdprConsent, uspConsent, gppConsent) { const { consentString, gdprApplies } = gdprConsent || {}; if (gdprApplies) { @@ -300,6 +326,11 @@ function replaceUsersyncMacros(url, gdprConsent, uspConsent) { url = url.replace('{{.USPrivacy}}', uspConsent); } + if (gppConsent) { + if (gppConsent?.gppString) url = url.replace('{{.GPP}}', gppConsent.gppString); + if (gppConsent?.applicableSections?.length) url = url.replace('{{.GPPSID}}', gppConsent.applicableSections.join(',')); + } + return url; }; From 72e2101bd64e31d887904b3e9d3dd4ed93b2adb9 Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Thu, 23 Nov 2023 04:47:05 +0300 Subject: [PATCH 02/18] changed test for nextMillenniumBidAdapter --- modules/nextMillenniumBidAdapter.js | 2 +- .../modules/nextMillenniumBidAdapter_spec.js | 60 ++++++++++++++++--- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index ff4c3ee28b4..0ab8ab3ddd2 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -260,7 +260,7 @@ export const spec = { syncUrlQuery.push('gpp=' + gppConsent.gppString + '&gpp_sid=' + gppConsent?.applicableSections?.join(',')); } - const type = syncOptions.iframeEnabled && 'iframe' || 'image'; + const type = (syncOptions.iframeEnabled && 'iframe') || 'image'; syncUrlQuery.push('type=' + type); pixels.push({ type, diff --git a/test/spec/modules/nextMillenniumBidAdapter_spec.js b/test/spec/modules/nextMillenniumBidAdapter_spec.js index 564788c8b56..22852b4075a 100644 --- a/test/spec/modules/nextMillenniumBidAdapter_spec.js +++ b/test/spec/modules/nextMillenniumBidAdapter_spec.js @@ -11,20 +11,54 @@ describe('nextMillenniumBidAdapterTests', function() { params: { placement_id: '-1' }, sizes: [[300, 250]], uspConsent: '1---', + gppConsent: { + gppString: 'DBACNYA~CPXxRfAPXxR', + applicableSections: [7], + }, + gdprConsent: { consentString: 'kjfdniwjnifwenrif3', gdprApplies: true }, + ortb2: { device: { w: 1500, h: 1000 }, + site: { domain: 'example.com', page: 'http://example.com' } } + }]; + + const bidRequestData2 = [ + { + adUnitCode: 'test-div', + bidId: 'bid1234', + auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', + bidder: 'nextMillennium', + params: { placement_id: '-1' }, + sizes: [[300, 250]], + + ortb2: { + device: { + w: 1500, + h: 1000 + }, + + site: { + domain: 'example.com', + page: 'http://example.com' + }, + + regs: { + gpp: 'DBACNYA~CPXxRfAPXxR', + gpp_sid: [7, 8], + }, + } } ]; @@ -49,7 +83,7 @@ describe('nextMillenniumBidAdapterTests', function() { cur: 'USD', ext: { sync: { - image: ['urlA?gdpr={{.GDPR}}'], + image: ['urlA?gdpr={{.GDPR}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}'], iframe: ['urlB'], } } @@ -117,26 +151,34 @@ describe('nextMillenniumBidAdapterTests', function() { }, ]; - it('Request params check with GDPR and USP Consent', function () { + it('Request params check with GDPR and USP Consent and GPP Consent', function () { const request = spec.buildRequests(bidRequestData, bidRequestData[0]); expect(JSON.parse(request[0].data).user.ext.consent).to.equal('kjfdniwjnifwenrif3'); expect(JSON.parse(request[0].data).regs.ext.us_privacy).to.equal('1---'); expect(JSON.parse(request[0].data).regs.ext.gdpr).to.equal(1); + expect(JSON.parse(request[0].data).regs.gpp).to.equal('DBACNYA~CPXxRfAPXxR'); + expect(JSON.stringify(JSON.parse(request[0].data).regs.gpp_sid)).to.equal('[7]'); + + const request2 = spec.buildRequests(bidRequestData2, bidRequestData2[0]); + expect(JSON.parse(request2[0].data).regs.gpp).to.equal('DBACNYA~CPXxRfAPXxR'); + expect(JSON.stringify(JSON.parse(request2[0].data).regs.gpp_sid)).to.equal('[7,8]'); }); it('Test getUserSyncs function', function () { + const {gdprConsent, uspConsent, gppConsent} = bidRequestData[0]; const syncOptions = { 'iframeEnabled': false, 'pixelEnabled': true } - let userSync = spec.getUserSyncs(syncOptions, [serverResponse], bidRequestData[0].gdprConsent, bidRequestData[0].uspConsent); + + let userSync = spec.getUserSyncs(syncOptions, [serverResponse], gdprConsent, uspConsent, gppConsent); expect(userSync).to.be.an('array').with.lengthOf(1); expect(userSync[0].type).to.equal('image'); - expect(userSync[0].url).to.equal('urlA?gdpr=1'); + expect(userSync[0].url).to.equal('urlA?gdpr=1&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7'); syncOptions.iframeEnabled = true; syncOptions.pixelEnabled = false; - userSync = spec.getUserSyncs(syncOptions, [serverResponse], bidRequestData[0].gdprConsent, bidRequestData[0].uspConsent); + userSync = spec.getUserSyncs(syncOptions, [serverResponse], gdprConsent, uspConsent); expect(userSync).to.be.an('array').with.lengthOf(1); expect(userSync[0].type).to.equal('iframe'); expect(userSync[0].url).to.equal('urlB'); @@ -147,10 +189,10 @@ describe('nextMillenniumBidAdapterTests', function() { 'iframeEnabled': true, 'pixelEnabled': false } - let userSync = spec.getUserSyncs(syncOptions, [], bidRequestData[0].gdprConsent, bidRequestData[0].uspConsent); + let userSync = spec.getUserSyncs(syncOptions, [], bidRequestData[0].gdprConsent, bidRequestData[0].uspConsent, bidRequestData[0].gppConsent); expect(userSync).to.be.an('array') expect(userSync[0].type).to.equal('iframe') - expect(userSync[0].url).to.equal('https://cookies.nextmillmedia.com/sync?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&type=iframe') + expect(userSync[0].url).to.equal('https://cookies.nextmillmedia.com/sync?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7&type=iframe') }) it('Test getUserSyncs function if GDPR is undefined', function () { @@ -162,7 +204,7 @@ describe('nextMillenniumBidAdapterTests', function() { let userSync = spec.getUserSyncs(syncOptions, [serverResponse], undefined, bidRequestData[0].uspConsent); expect(userSync).to.be.an('array').with.lengthOf(1); expect(userSync[0].type).to.equal('image'); - expect(userSync[0].url).to.equal('urlA?gdpr=0'); + expect(userSync[0].url).to.equal('urlA?gdpr=0&gpp={{.GPP}}&gpp_sid={{.GPPSID}}'); }); it('Request params check without GDPR Consent', function () { @@ -190,7 +232,7 @@ describe('nextMillenniumBidAdapterTests', function() { it('Check if refresh_count param is incremented', function() { const request = spec.buildRequests(bidRequestData); - expect(JSON.parse(request[0].data).ext.nextMillennium.refresh_count).to.equal(3); + expect(JSON.parse(request[0].data).ext.nextMillennium.refresh_count).to.equal(4); }); it('Check if domain was added', function() { From 93f578eddbb87fddf478fb0f53d318d4dfb78d66 Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Fri, 24 Nov 2023 04:52:41 +0300 Subject: [PATCH 03/18] added some tests --- modules/nextMillenniumBidAdapter.js | 223 ++++---- .../modules/nextMillenniumBidAdapter_spec.js | 475 ++++++++++++++---- 2 files changed, 465 insertions(+), 233 deletions(-) diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index 0ab8ab3ddd2..47751775f6b 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -21,10 +21,11 @@ import * as events from '../src/events.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {getRefererInfo} from '../src/refererDetection.js'; +const NM_VERSION = '3.0.0' const BIDDER_CODE = 'nextMillennium'; const ENDPOINT = 'https://pbs.nextmillmedia.com/openrtb2/auction'; const TEST_ENDPOINT = 'https://test.pbs.nextmillmedia.com/openrtb2/auction'; -const SYNC_ENDPOINT = 'https://cookies.nextmillmedia.com/sync?'; +const SYNC_ENDPOINT = 'https://cookies.nextmillmedia.com/sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&type={{.TYPE_PIXEL}}'; const REPORT_ENDPOINT = 'https://report2.hb.brainlyads.com/statistics/metric'; const TIME_TO_LIVE = 360; const VIDEO_PARAMS = [ @@ -70,26 +71,25 @@ export const spec = { const id = getPlacementId(bid); const auctionId = bid.auctionId; const bidId = bid.bidId; - let sizes = bid.sizes; - if (sizes && !Array.isArray(sizes[0])) sizes = [sizes]; const site = getSiteObj(); const device = getDeviceObj(); const postBody = { - 'id': bidderRequest?.bidderRequestId, - 'ext': { - 'prebid': { - 'storedrequest': { - 'id': id - } + id: bidderRequest?.bidderRequestId, + ext: { + prebid: { + storedrequest: { + id, + }, }, - 'nextMillennium': { - 'refresh_count': window.nmmRefreshCounts[bid.adUnitCode]++, - 'elOffsets': getBoundingClient(bid), - 'scrollTop': window.pageYOffset || document.documentElement.scrollTop - } + nextMillennium: { + nm_version: NM_VERSION, + refresh_count: window.nmmRefreshCounts[bid.adUnitCode]++, + elOffsets: getBoundingClient(bid), + scrollTop: window.pageYOffset || document.documentElement.scrollTop, + }, }, device, @@ -97,65 +97,8 @@ export const spec = { imp: [] }; - const imp = { - id: bid.adUnitCode, - ext: { - prebid: { - storedrequest: {id} - } - } - }; - - if (deepAccess(bid, 'mediaTypes.banner')) { - imp.banner = { - format: (sizes || []).map(s => { return {w: s[0], h: s[1]} }) - }; - }; - - const video = deepAccess(bid, 'mediaTypes.video'); - if (video) { - imp.video = getDefinedParams(video, VIDEO_PARAMS); - if (video.playerSize) { - imp.video = Object.assign( - imp.video, parseGPTSingleSizeArrayToRtbSize(video.playerSize[0]) || {} - ); - } else if (video.w && video.h) { - imp.video.w = video.w; - imp.video.h = video.h; - }; - }; - - postBody.imp.push(imp); - - const gdprConsent = bidderRequest?.gdprConsent; - const uspConsent = bidderRequest?.uspConsent; - let gppConsent = bidderRequest?.gppConsent?.gppString && bidderRequest?.gppConsent; - if (!gppConsent && bidderRequest?.ortb2?.regs?.gpp) gppConsent = bidderRequest?.ortb2?.regs; - - if (gdprConsent || uspConsent || gppConsent) { - postBody.regs = { ext: {} }; - - if (uspConsent) { - postBody.regs.ext.us_privacy = uspConsent; - }; - - if (gppConsent) { - postBody.regs.gpp = gppConsent?.gppString || gppConsent?.gpp; - postBody.regs.gpp_sid = bidderRequest.gppConsent?.applicableSections || gppConsent?.gpp_sid; - }; - - if (gdprConsent) { - if (typeof gdprConsent.gdprApplies !== 'undefined') { - postBody.regs.ext.gdpr = gdprConsent.gdprApplies ? 1 : 0; - }; - - if (typeof gdprConsent.consentString !== 'undefined') { - postBody.user = { - ext: { consent: gdprConsent.consentString } - }; - }; - }; - }; + postBody.imp.push(getImp(bid, id)); + setConsentStrings(postBody, bidderRequest) const urlParameters = parseUrl(getWindowTop().location.href).search; const isTest = urlParameters['pbs'] && urlParameters['pbs'] === 'test'; @@ -228,44 +171,26 @@ export const spec = { }, getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent, gppConsent) { + if (!syncOptions.iframeEnabled && !syncOptions.pixelEnabled) return []; + const pixels = []; + const getSetPixelFunc = type => url => { pixels.push({type, url: replaceUsersyncMacros(url, gdprConsent, uspConsent, gppConsent, type)}) }; + const getSetPixelsFunc = type => response => { deepAccess(response, `body.ext.sync.${type}`, []).forEach(getSetPixelFunc(type)) }; + + const setPixel = (type, url) => { (getSetPixelFunc(type))(url) }; + const setPixelImages = getSetPixelsFunc('image'); + const setPixelIframes = getSetPixelsFunc('iframe'); if (isArray(responses)) { responses.forEach(response => { - if (syncOptions.pixelEnabled) { - deepAccess(response, 'body.ext.sync.image', []).forEach(imgUrl => { - pixels.push({ - type: 'image', - url: replaceUsersyncMacros(imgUrl, gdprConsent, uspConsent, gppConsent) - }); - }) - } - - if (syncOptions.iframeEnabled) { - deepAccess(response, 'body.ext.sync.iframe', []).forEach(iframeUrl => { - pixels.push({ - type: 'iframe', - url: replaceUsersyncMacros(iframeUrl, gdprConsent, uspConsent, gppConsent) - }); - }) - } + if (syncOptions.pixelEnabled) setPixelImages(response); + if (syncOptions.iframeEnabled) setPixelIframes(response); }) } - if (!pixels.length && (syncOptions.iframeEnabled || syncOptions.pixelEnabled)) { - const syncUrlQuery = []; - if (gdprConsent?.gdprApplies) syncUrlQuery.push('gdpr=1&gdpr_consent=' + gdprConsent.consentString); - if (uspConsent) syncUrlQuery.push('us_privacy=' + uspConsent); - if (gppConsent?.gppString && gppConsent?.applicableSections?.length) { - syncUrlQuery.push('gpp=' + gppConsent.gppString + '&gpp_sid=' + gppConsent?.applicableSections?.join(',')); - } - - const type = (syncOptions.iframeEnabled && 'iframe') || 'image'; - syncUrlQuery.push('type=' + type); - pixels.push({ - type, - url: SYNC_ENDPOINT + syncUrlQuery.join('&'), - }); + if (!pixels.length) { + if (syncOptions.pixelEnabled) setPixel('image', SYNC_ENDPOINT); + if (syncOptions.iframeEnabled) setPixel('iframe', SYNC_ENDPOINT); } return pixels; @@ -307,29 +232,81 @@ export const spec = { }, }; -function replaceUsersyncMacros(url, gdprConsent, uspConsent, gppConsent) { - const { consentString, gdprApplies } = gdprConsent || {}; +export function getImp(bid, id) { + const imp = { + id: bid.adUnitCode, + ext: { + prebid: { + storedrequest: { + id, + }, + }, + }, + }; - if (gdprApplies) { - const gdpr = Number(gdprApplies); - url = url.replace('{{.GDPR}}', gdpr); + const banner = deepAccess(bid, 'mediaTypes.banner'); + if (banner) { + imp.banner = { + format: (banner?.sizes || []).map(s => { return {w: s[0], h: s[1]} }), + }; + }; - if (gdpr == 1 && consentString && consentString.length > 0) { - url = url.replace('{{.GDPRConsent}}', consentString); - } - } else { - url = url.replace('{{.GDPR}}', 0); - url = url.replace('{{.GDPRConsent}}', ''); - } + const video = deepAccess(bid, 'mediaTypes.video'); + if (video) { + imp.video = getDefinedParams(video, VIDEO_PARAMS); + if (video.playerSize) { + imp.video = Object.assign(imp.video, parseGPTSingleSizeArrayToRtbSize(video.playerSize) || {}); + } else if (video.w && video.h) { + imp.video.w = video.w; + imp.video.h = video.h; + }; + }; - if (uspConsent) { - url = url.replace('{{.USPrivacy}}', uspConsent); - } + return imp; +}; - if (gppConsent) { - if (gppConsent?.gppString) url = url.replace('{{.GPP}}', gppConsent.gppString); - if (gppConsent?.applicableSections?.length) url = url.replace('{{.GPPSID}}', gppConsent.applicableSections.join(',')); - } +export function setConsentStrings(postBody = {}, bidderRequest) { + const gdprConsent = bidderRequest?.gdprConsent; + const uspConsent = bidderRequest?.uspConsent; + let gppConsent = bidderRequest?.gppConsent?.gppString && bidderRequest?.gppConsent; + if (!gppConsent && bidderRequest?.ortb2?.regs?.gpp) gppConsent = bidderRequest?.ortb2?.regs; + + if (gdprConsent || uspConsent || gppConsent) { + postBody.regs = { ext: {} }; + + if (uspConsent) { + postBody.regs.ext.us_privacy = uspConsent; + }; + + if (gppConsent) { + postBody.regs.gpp = gppConsent?.gppString || gppConsent?.gpp; + postBody.regs.gpp_sid = bidderRequest.gppConsent?.applicableSections || gppConsent?.gpp_sid; + }; + + if (gdprConsent) { + if (typeof gdprConsent.gdprApplies !== 'undefined') { + postBody.regs.ext.gdpr = gdprConsent.gdprApplies ? 1 : 0; + }; + + if (typeof gdprConsent.consentString !== 'undefined') { + postBody.user = { + ext: { consent: gdprConsent.consentString }, + }; + }; + }; + }; +}; + +export function replaceUsersyncMacros(url, gdprConsent = {}, uspConsent = '', gppConsent = {}, type = '') { + const { consentString = '', gdprApplies = false } = gdprConsent; + const gdpr = Number(gdprApplies); + url = url + .replace('{{.GDPR}}', gdpr) + .replace('{{.GDPRConsent}}', consentString) + .replace('{{.USPrivacy}}', uspConsent) + .replace('{{.GPP}}', gppConsent.gppString || '') + .replace('{{.GPPSID}}', (gppConsent.applicableSections || []).join(',')) + .replace('{{.TYPE_PIXEL}}', type); return url; }; diff --git a/test/spec/modules/nextMillenniumBidAdapter_spec.js b/test/spec/modules/nextMillenniumBidAdapter_spec.js index 22852b4075a..1cbc13b180f 100644 --- a/test/spec/modules/nextMillenniumBidAdapter_spec.js +++ b/test/spec/modules/nextMillenniumBidAdapter_spec.js @@ -1,66 +1,384 @@ import { expect } from 'chai'; -import { spec } from 'modules/nextMillenniumBidAdapter.js'; +import { + spec, + getImp, + setConsentStrings, + replaceUsersyncMacros, +} from 'modules/nextMillenniumBidAdapter.js'; + +describe('nextMillenniumBidAdapterTests', () => { + describe('function getImp', () => { + const dataTests = [ + { + title: 'imp - banner', + data: { + id: '123', + bid: { + mediaTypes: {banner: {sizes: [[300, 250], [320, 250]]}}, + adUnitCode: 'test-banner-1', + }, + }, -describe('nextMillenniumBidAdapterTests', function() { - const bidRequestData = [ - { - adUnitCode: 'test-div', - bidId: 'bid1234', - auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', - bidder: 'nextMillennium', - params: { placement_id: '-1' }, - sizes: [[300, 250]], - uspConsent: '1---', - gppConsent: { - gppString: 'DBACNYA~CPXxRfAPXxR', - applicableSections: [7], + expected: { + id: 'test-banner-1', + ext: {prebid: {storedrequest: {id: '123'}}}, + banner: {format: [{w: 300, h: 250}, {w: 320, h: 250}]}, + }, }, - gdprConsent: { - consentString: 'kjfdniwjnifwenrif3', - gdprApplies: true + { + title: 'imp - video', + data: { + id: '234', + bid: { + mediaTypes: {video: {playerSize: [400, 300]}}, + adUnitCode: 'test-video-1', + }, + }, + + expected: { + id: 'test-video-1', + ext: {prebid: {storedrequest: {id: '234'}}}, + video: {w: 400, h: 300}, + }, }, + ]; - ortb2: { - device: { - w: 1500, - h: 1000 + for (let {title, data, expected} of dataTests) { + it(title, () => { + const {bid, id} = data; + const imp = getImp(bid, id); + expect(imp).to.deep.equal(expected); + }); + } + }); + + describe('function setConsentStrings', () => { + const dataTests = [ + { + title: 'full: uspConsent, gdprConsent and gppConsent', + data: { + postBody: {}, + bidderRequest: { + uspConsent: '1---', + gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7]}, + gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, + ortb2: {regs: {gpp: 'DSFHFHWEUYVDC', gpp_sid: [8, 9, 10]}}, + }, }, - site: { - domain: 'example.com', - page: 'http://example.com' - } - } - }]; + expected: { + user: {ext: {consent: 'kjfdniwjnifwenrif3'}}, + regs: { + gpp: 'DBACNYA~CPXxRfAPXxR', + gpp_sid: [7], + ext: {gdpr: 1, us_privacy: '1---'}, + }, + }, + }, - const bidRequestData2 = [ - { - adUnitCode: 'test-div', - bidId: 'bid1234', - auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', - bidder: 'nextMillennium', - params: { placement_id: '-1' }, - sizes: [[300, 250]], + { + title: 'gdprConsent(false) and ortb2(gpp)', + data: { + postBody: {}, + bidderRequest: { + gdprConsent: {consentString: 'ewtewbefbawyadexv', gdprApplies: false}, + ortb2: {regs: {gpp: 'DSFHFHWEUYVDC', gpp_sid: [8, 9, 10]}}, + }, + }, + + expected: { + user: {ext: {consent: 'ewtewbefbawyadexv'}}, + regs: { + gpp: 'DSFHFHWEUYVDC', + gpp_sid: [8, 9, 10], + ext: {gdpr: 0}, + }, + }, + }, + + { + title: 'gdprConsent(false)', + data: { + postBody: {}, + bidderRequest: {gdprConsent: {gdprApplies: false}}, + }, + + expected: { + regs: {ext: {gdpr: 0}}, + }, + }, + + { + title: 'empty', + data: { + postBody: {}, + bidderRequest: {}, + }, + + expected: {}, + }, + ]; + + for (let {title, data, expected} of dataTests) { + it(title, () => { + const {postBody, bidderRequest} = data; + setConsentStrings(postBody, bidderRequest); + expect(postBody).to.deep.equal(expected); + }); + } + }); + + describe('function replaceUsersyncMacros', () => { + const dataTests = [ + { + title: 'url with all macroses - consents full: uspConsent, gdprConsent and gppConsent', + data: { + url: 'https://some.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&type={{.TYPE_PIXEL}}', + uspConsent: '1---', + gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, + gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, + type: 'image', + }, + + expected: 'https://some.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8&type=image', + }, + + { + title: 'url with some macroses - consents full: uspConsent, gdprConsent and gppConsent', + data: { + url: 'https://some.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&type={{.TYPE_PIXEL}}', + uspConsent: '1---', + gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, + gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: false}, + type: 'iframe', + }, + + expected: 'https://some.url?gdpr=0&gdpr_consent=kjfdniwjnifwenrif3&type=iframe', + }, + + { + title: 'url without macroses - consents full: uspConsent, gdprConsent and gppConsent', + data: { + url: 'https://some.url?param1=value1¶m2=value2', + uspConsent: '1---', + gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, + gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: false}, + type: 'iframe', + }, + + expected: 'https://some.url?param1=value1¶m2=value2', + }, + + { + title: 'url with all macroses - consents are empty', + data: { + url: 'https://some.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&type={{.TYPE_PIXEL}}', + }, + + expected: 'https://some.url?gdpr=0&gdpr_consent=&us_privacy=&gpp=&gpp_sid=&type=', + }, + ]; + + for (let {title, data, expected} of dataTests) { + it(title, () => { + const {url, gdprConsent, uspConsent, gppConsent, type} = data; + const newUrl = replaceUsersyncMacros(url, gdprConsent, uspConsent, gppConsent, type); + expect(newUrl).to.equal(expected); + }); + } + }); + + describe('function spec.getUserSyncs', () => { + const dataTests = [ + { + title: 'pixels from responses ({iframeEnabled: true, pixelEnabled: true})', + data: { + syncOptions: {iframeEnabled: true, pixelEnabled: true}, + responses: [ + {body: {ext: {sync: { + image: [ + 'https://some.1.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.2.url?us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.3.url?param=1234', + ], + + iframe: [ + 'https://some.4.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.5.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}', + ], + }}}}, + + {body: {ext: {sync: { + iframe: [ + 'https://some.6.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.7.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}', + ], + }}}}, + + {body: {ext: {sync: { + image: [ + 'https://some.8.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + ], + }}}}, + ], + + uspConsent: '1---', + gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, + gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, + }, + + expected: [ + {type: 'image', url: 'https://some.1.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, + {type: 'image', url: 'https://some.2.url?us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, + {type: 'image', url: 'https://some.3.url?param=1234'}, + {type: 'iframe', url: 'https://some.4.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, + {type: 'iframe', url: 'https://some.5.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---'}, + {type: 'iframe', url: 'https://some.6.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, + {type: 'iframe', url: 'https://some.7.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---'}, + {type: 'image', url: 'https://some.8.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, + ], + }, + + { + title: 'pixels from responses ({iframeEnabled: true, pixelEnabled: false})', + data: { + syncOptions: {iframeEnabled: true, pixelEnabled: false}, + responses: [ + {body: {ext: {sync: { + image: [ + 'https://some.1.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.2.url?us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.3.url?param=1234', + ], + + iframe: [ + 'https://some.4.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.5.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}', + ], + }}}}, + ], - ortb2: { - device: { - w: 1500, - h: 1000 + uspConsent: '1---', + gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, + gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, }, - site: { - domain: 'example.com', - page: 'http://example.com' + expected: [ + {type: 'iframe', url: 'https://some.4.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, + {type: 'iframe', url: 'https://some.5.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---'}, + ], + }, + + { + title: 'pixels from responses ({iframeEnabled: false, pixelEnabled: true})', + data: { + syncOptions: {iframeEnabled: false, pixelEnabled: true}, + responses: [ + {body: {ext: {sync: { + image: [ + 'https://some.1.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.2.url?us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.3.url?param=1234', + ], + + iframe: [ + 'https://some.4.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.5.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}', + ], + }}}}, + ], + + uspConsent: '1---', + gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, + gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, }, - regs: { - gpp: 'DBACNYA~CPXxRfAPXxR', - gpp_sid: [7, 8], + expected: [ + {type: 'image', url: 'https://some.1.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, + {type: 'image', url: 'https://some.2.url?us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, + {type: 'image', url: 'https://some.3.url?param=1234'}, + ], + }, + + { + title: 'pixels - responses is empty ({iframeEnabled: true, pixelEnabled: true})', + data: { + syncOptions: {iframeEnabled: true, pixelEnabled: true}, + responses: [], + uspConsent: '1---', + gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, + gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, + }, + + expected: [ + {type: 'image', url: 'https://cookies.nextmillmedia.com/sync?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8&type=image'}, + {type: 'iframe', url: 'https://cookies.nextmillmedia.com/sync?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8&type=iframe'}, + ], + }, + + { + title: 'pixels - responses is empty ({iframeEnabled: true, pixelEnabled: false})', + data: { + syncOptions: {iframeEnabled: true, pixelEnabled: false}, + uspConsent: '1---', + gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, + gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, }, + + expected: [ + {type: 'iframe', url: 'https://cookies.nextmillmedia.com/sync?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8&type=iframe'}, + ], + }, + + { + title: 'pixels - responses is empty ({iframeEnabled: false, pixelEnabled: false})', + data: { + syncOptions: {iframeEnabled: false, pixelEnabled: false}, + uspConsent: '1---', + gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, + gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, + }, + + expected: [], + }, + ]; + + for (let {title, data, expected} of dataTests) { + it(title, () => { + const {syncOptions, responses, gdprConsent, uspConsent, gppConsent} = data; + const pixels = spec.getUserSyncs(syncOptions, responses, gdprConsent, uspConsent, gppConsent); + expect(pixels).to.deep.equal(expected); + }); + } + }); + + const bidRequestData = [{ + adUnitCode: 'test-div', + bidId: 'bid1234', + auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', + bidder: 'nextMillennium', + params: { placement_id: '-1' }, + sizes: [[300, 250]], + uspConsent: '1---', + gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7]}, + gdprConsent: { + consentString: 'kjfdniwjnifwenrif3', + gdprApplies: true + }, + + ortb2: { + device: { + w: 1500, + h: 1000 + }, + + site: { + domain: 'example.com', + page: 'http://example.com' } } - ]; + }]; const serverResponse = { body: { @@ -151,69 +469,6 @@ describe('nextMillenniumBidAdapterTests', function() { }, ]; - it('Request params check with GDPR and USP Consent and GPP Consent', function () { - const request = spec.buildRequests(bidRequestData, bidRequestData[0]); - expect(JSON.parse(request[0].data).user.ext.consent).to.equal('kjfdniwjnifwenrif3'); - expect(JSON.parse(request[0].data).regs.ext.us_privacy).to.equal('1---'); - expect(JSON.parse(request[0].data).regs.ext.gdpr).to.equal(1); - expect(JSON.parse(request[0].data).regs.gpp).to.equal('DBACNYA~CPXxRfAPXxR'); - expect(JSON.stringify(JSON.parse(request[0].data).regs.gpp_sid)).to.equal('[7]'); - - const request2 = spec.buildRequests(bidRequestData2, bidRequestData2[0]); - expect(JSON.parse(request2[0].data).regs.gpp).to.equal('DBACNYA~CPXxRfAPXxR'); - expect(JSON.stringify(JSON.parse(request2[0].data).regs.gpp_sid)).to.equal('[7,8]'); - }); - - it('Test getUserSyncs function', function () { - const {gdprConsent, uspConsent, gppConsent} = bidRequestData[0]; - const syncOptions = { - 'iframeEnabled': false, - 'pixelEnabled': true - } - - let userSync = spec.getUserSyncs(syncOptions, [serverResponse], gdprConsent, uspConsent, gppConsent); - expect(userSync).to.be.an('array').with.lengthOf(1); - expect(userSync[0].type).to.equal('image'); - expect(userSync[0].url).to.equal('urlA?gdpr=1&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7'); - - syncOptions.iframeEnabled = true; - syncOptions.pixelEnabled = false; - userSync = spec.getUserSyncs(syncOptions, [serverResponse], gdprConsent, uspConsent); - expect(userSync).to.be.an('array').with.lengthOf(1); - expect(userSync[0].type).to.equal('iframe'); - expect(userSync[0].url).to.equal('urlB'); - }); - - it('Test getUserSyncs with no response', function () { - const syncOptions = { - 'iframeEnabled': true, - 'pixelEnabled': false - } - let userSync = spec.getUserSyncs(syncOptions, [], bidRequestData[0].gdprConsent, bidRequestData[0].uspConsent, bidRequestData[0].gppConsent); - expect(userSync).to.be.an('array') - expect(userSync[0].type).to.equal('iframe') - expect(userSync[0].url).to.equal('https://cookies.nextmillmedia.com/sync?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7&type=iframe') - }) - - it('Test getUserSyncs function if GDPR is undefined', function () { - const syncOptions = { - 'iframeEnabled': false, - 'pixelEnabled': true - } - - let userSync = spec.getUserSyncs(syncOptions, [serverResponse], undefined, bidRequestData[0].uspConsent); - expect(userSync).to.be.an('array').with.lengthOf(1); - expect(userSync[0].type).to.equal('image'); - expect(userSync[0].url).to.equal('urlA?gdpr=0&gpp={{.GPP}}&gpp_sid={{.GPPSID}}'); - }); - - it('Request params check without GDPR Consent', function () { - delete bidRequestData[0].gdprConsent - const request = spec.buildRequests(bidRequestData, bidRequestData[0]); - expect(JSON.parse(request[0].data).regs.ext.gdpr).to.be.undefined; - expect(JSON.parse(request[0].data).regs.ext.us_privacy).to.equal('1---'); - }); - it('validate_generated_params', function() { const request = spec.buildRequests(bidRequestData, {bidderRequestId: 'mock-uuid'}); expect(request[0].bidId).to.equal('bid1234'); @@ -232,7 +487,7 @@ describe('nextMillenniumBidAdapterTests', function() { it('Check if refresh_count param is incremented', function() { const request = spec.buildRequests(bidRequestData); - expect(JSON.parse(request[0].data).ext.nextMillennium.refresh_count).to.equal(4); + expect(JSON.parse(request[0].data).ext.nextMillennium.refresh_count).to.equal(1); }); it('Check if domain was added', function() { From 97396e269aa79f0000676ad4db7ce8bd609f9810 Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Sat, 25 Nov 2023 03:56:42 +0300 Subject: [PATCH 04/18] added site.pagecat, site.content.cat and site.content.language to request --- modules/nextMillenniumBidAdapter.js | 16 +++++- .../modules/nextMillenniumBidAdapter_spec.js | 57 ++++++++++++++++++- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index 47751775f6b..387924aa583 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -2,6 +2,7 @@ import { _each, createTrackPixelHtml, deepAccess, + deepSetValue, getBidIdParameter, getDefinedParams, getWindowTop, @@ -22,6 +23,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import {getRefererInfo} from '../src/refererDetection.js'; const NM_VERSION = '3.0.0' +const GVLID = 1060; const BIDDER_CODE = 'nextMillennium'; const ENDPOINT = 'https://pbs.nextmillmedia.com/openrtb2/auction'; const TEST_ENDPOINT = 'https://test.pbs.nextmillmedia.com/openrtb2/auction'; @@ -40,7 +42,11 @@ const VIDEO_PARAMS = [ 'startdelay', ]; -const GVLID = 1060; +const ALLOWED_ORTB2_PARAMETERS = [ + 'site.pagecat', + 'site.content.cat', + 'site.content.language', +] const sendingDataStatistic = initSendingDataStatistic(); events.on(CONSTANTS.EVENTS.AUCTION_INIT, auctionInitHandler); @@ -99,6 +105,7 @@ export const spec = { postBody.imp.push(getImp(bid, id)); setConsentStrings(postBody, bidderRequest) + setOrtb2Parameters(postBody, bidderRequest?.ortb2) const urlParameters = parseUrl(getWindowTop().location.href).search; const isTest = urlParameters['pbs'] && urlParameters['pbs'] === 'test'; @@ -297,6 +304,13 @@ export function setConsentStrings(postBody = {}, bidderRequest) { }; }; +export function setOrtb2Parameters(postBody, ortb2 = {}) { + for(let parameter of ALLOWED_ORTB2_PARAMETERS) { + const value = deepAccess(ortb2, parameter) + if (value) deepSetValue(postBody, parameter, value) + } +} + export function replaceUsersyncMacros(url, gdprConsent = {}, uspConsent = '', gppConsent = {}, type = '') { const { consentString = '', gdprApplies = false } = gdprConsent; const gdpr = Number(gdprApplies); diff --git a/test/spec/modules/nextMillenniumBidAdapter_spec.js b/test/spec/modules/nextMillenniumBidAdapter_spec.js index 1cbc13b180f..8b512218d56 100644 --- a/test/spec/modules/nextMillenniumBidAdapter_spec.js +++ b/test/spec/modules/nextMillenniumBidAdapter_spec.js @@ -1,9 +1,10 @@ import { expect } from 'chai'; import { - spec, getImp, - setConsentStrings, replaceUsersyncMacros, + setConsentStrings, + setOrtb2Parameters, + spec, } from 'modules/nextMillenniumBidAdapter.js'; describe('nextMillenniumBidAdapterTests', () => { @@ -353,6 +354,58 @@ describe('nextMillenniumBidAdapterTests', () => { } }); + describe('function setOrtb2Parameters', () => { + const dataTests = [ + { + title: 'site.pagecat, site.content.cat and site.content.language', + data: { + postBody: {}, + ortb2: {site: { + pagecat: ['IAB2-11', 'IAB2-12', 'IAB2-14'], + content: {cat: ['IAB2-11', 'IAB2-12', 'IAB2-14'], language: 'EN'}, + }}, + }, + + expected: {site: { + pagecat: ['IAB2-11', 'IAB2-12', 'IAB2-14'], + content: {cat: ['IAB2-11', 'IAB2-12', 'IAB2-14'], language: 'EN'}, + }}, + }, + + { + title: 'only site.content.language', + data: { + postBody: {site: {domain: 'some.domain'}}, + ortb2: {site: { + content: {language: 'EN'}, + }}, + }, + + expected: {site: { + domain: 'some.domain', + content: {language: 'EN'}, + }}, + }, + + { + title: 'object ortb2 is empty', + data: { + postBody: {imp: []}, + }, + + expected: {imp: []}, + }, + ]; + + for (let {title, data, expected} of dataTests) { + it(title, () => { + const {postBody, ortb2} = data; + setOrtb2Parameters(postBody, ortb2); + expect(postBody).to.deep.equal(expected); + }); + } + }); + const bidRequestData = [{ adUnitCode: 'test-div', bidId: 'bid1234', From a108dad1e9e074b87b10196ee7ef679cdeb45f09 Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Sat, 25 Nov 2023 04:56:56 +0300 Subject: [PATCH 05/18] lint fix --- modules/nextMillenniumBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index 387924aa583..fa4093a3a21 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -305,7 +305,7 @@ export function setConsentStrings(postBody = {}, bidderRequest) { }; export function setOrtb2Parameters(postBody, ortb2 = {}) { - for(let parameter of ALLOWED_ORTB2_PARAMETERS) { + for (let parameter of ALLOWED_ORTB2_PARAMETERS) { const value = deepAccess(ortb2, parameter) if (value) deepSetValue(postBody, parameter, value) } From b6865e7ecfdb53db064e92f113f211dc67c1a974 Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Sat, 25 Nov 2023 05:45:14 +0300 Subject: [PATCH 06/18] formated code --- modules/nextMillenniumBidAdapter.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index fa4093a3a21..bde5db4446a 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -22,7 +22,7 @@ import * as events from '../src/events.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {getRefererInfo} from '../src/refererDetection.js'; -const NM_VERSION = '3.0.0' +const NM_VERSION = '3.0.0'; const GVLID = 1060; const BIDDER_CODE = 'nextMillennium'; const ENDPOINT = 'https://pbs.nextmillmedia.com/openrtb2/auction'; @@ -46,7 +46,7 @@ const ALLOWED_ORTB2_PARAMETERS = [ 'site.pagecat', 'site.content.cat', 'site.content.language', -] +]; const sendingDataStatistic = initSendingDataStatistic(); events.on(CONSTANTS.EVENTS.AUCTION_INIT, auctionInitHandler); @@ -100,7 +100,7 @@ export const spec = { device, site, - imp: [] + imp: [], }; postBody.imp.push(getImp(bid, id)); @@ -156,8 +156,8 @@ export const spec = { netRevenue: true, ttl: TIME_TO_LIVE, meta: { - advertiserDomains: bid.adomain || [] - } + advertiserDomains: bid.adomain || [], + }, }; if (vastUrl || vastXml) { @@ -306,8 +306,8 @@ export function setConsentStrings(postBody = {}, bidderRequest) { export function setOrtb2Parameters(postBody, ortb2 = {}) { for (let parameter of ALLOWED_ORTB2_PARAMETERS) { - const value = deepAccess(ortb2, parameter) - if (value) deepSetValue(postBody, parameter, value) + const value = deepAccess(ortb2, parameter); + if (value) deepSetValue(postBody, parameter, value); } } From 763721a4d17c2cbeabd2f58daf0984eea9ca66f5 Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Sat, 25 Nov 2023 11:41:49 +0300 Subject: [PATCH 07/18] formated code --- modules/nextMillenniumBidAdapter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index bde5db4446a..310de260eaa 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -104,8 +104,8 @@ export const spec = { }; postBody.imp.push(getImp(bid, id)); - setConsentStrings(postBody, bidderRequest) - setOrtb2Parameters(postBody, bidderRequest?.ortb2) + setConsentStrings(postBody, bidderRequest); + setOrtb2Parameters(postBody, bidderRequest?.ortb2); const urlParameters = parseUrl(getWindowTop().location.href).search; const isTest = urlParameters['pbs'] && urlParameters['pbs'] === 'test'; From 03ffd760ec23a0d167d9bf0c7272ce47a7f10b49 Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Mon, 27 Nov 2023 15:32:40 +0300 Subject: [PATCH 08/18] formated code --- modules/nextMillenniumBidAdapter.js | 1 + package-lock.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index 310de260eaa..30b84a4fc68 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -30,6 +30,7 @@ const TEST_ENDPOINT = 'https://test.pbs.nextmillmedia.com/openrtb2/auction'; const SYNC_ENDPOINT = 'https://cookies.nextmillmedia.com/sync?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&type={{.TYPE_PIXEL}}'; const REPORT_ENDPOINT = 'https://report2.hb.brainlyads.com/statistics/metric'; const TIME_TO_LIVE = 360; + const VIDEO_PARAMS = [ 'api', 'linearity', diff --git a/package-lock.json b/package-lock.json index 4650db8f2ab..db2aa88735c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "prebid.js", - "version": "8.24.0-pre", + "version": "8.25.0-pre", "license": "Apache-2.0", "dependencies": { "@babel/core": "^7.16.7", From 9b7c16b40401f059f7b0d033743a7a6f0d374704 Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Fri, 1 Dec 2023 16:09:32 +0300 Subject: [PATCH 09/18] pachage-lock with prebid --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index db2aa88735c..bed20db8cd2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "prebid.js", - "version": "8.25.0-pre", + "version": "8.27.0-pre", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "prebid.js", - "version": "8.25.0-pre", + "version": "8.24.0-pre", "license": "Apache-2.0", "dependencies": { "@babel/core": "^7.16.7", @@ -45051,4 +45051,4 @@ "dev": true } } -} +} \ No newline at end of file From 281dd5404563a8c69312f857952de346920c0f4f Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Fri, 1 Dec 2023 16:10:54 +0300 Subject: [PATCH 10/18] pachage-lock with prebid --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index bed20db8cd2..4650db8f2ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "8.27.0-pre", + "version": "8.25.0-pre", "lockfileVersion": 2, "requires": true, "packages": { @@ -45051,4 +45051,4 @@ "dev": true } } -} \ No newline at end of file +} From d33f0786acdc9ac0557b20433705dab7a2bed71c Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Fri, 1 Dec 2023 18:36:46 +0300 Subject: [PATCH 11/18] formatted code --- modules/nextMillenniumBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index 30b84a4fc68..26d417b9baf 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -118,7 +118,7 @@ export const spec = { data: JSON.stringify(postBody), options: { contentType: 'text/plain', - withCredentials: true + withCredentials: true, }, bidId, From 28ccc934a5aad5b2b5f8ca096473a17a740cbe2f Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Sat, 9 Dec 2023 12:34:22 +0300 Subject: [PATCH 12/18] added device.sua, user.eids --- modules/nextMillenniumBidAdapter.js | 40 ++++++++++- .../modules/nextMillenniumBidAdapter_spec.js | 72 +++++++++++++++++++ 2 files changed, 109 insertions(+), 3 deletions(-) diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index 26d417b9baf..f1a806c29ae 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -14,6 +14,7 @@ import { triggerPixel, } from '../src/utils.js'; +import {getGlobal} from '../src/prebidGlobal.js'; import CONSTANTS from '../src/constants.json'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {config} from '../src/config.js'; @@ -22,7 +23,7 @@ import * as events from '../src/events.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {getRefererInfo} from '../src/refererDetection.js'; -const NM_VERSION = '3.0.0'; +const NM_VERSION = '3.1.0'; const GVLID = 1060; const BIDDER_CODE = 'nextMillennium'; const ENDPOINT = 'https://pbs.nextmillmedia.com/openrtb2/auction'; @@ -47,6 +48,7 @@ const ALLOWED_ORTB2_PARAMETERS = [ 'site.pagecat', 'site.content.cat', 'site.content.language', + 'device.sua', ]; const sendingDataStatistic = initSendingDataStatistic(); @@ -93,6 +95,7 @@ export const spec = { nextMillennium: { nm_version: NM_VERSION, + pbjs_version: getGlobal()?.version || undefined, refresh_count: window.nmmRefreshCounts[bid.adUnitCode]++, elOffsets: getBoundingClient(bid), scrollTop: window.pageYOffset || document.documentElement.scrollTop, @@ -107,6 +110,7 @@ export const spec = { postBody.imp.push(getImp(bid, id)); setConsentStrings(postBody, bidderRequest); setOrtb2Parameters(postBody, bidderRequest?.ortb2); + setEids(postBody, bid); const urlParameters = parseUrl(getWindowTop().location.href).search; const isTest = urlParameters['pbs'] && urlParameters['pbs'] === 'test'; @@ -312,6 +316,12 @@ export function setOrtb2Parameters(postBody, ortb2 = {}) { } } +export function setEids(postBody, bid) { + if (!isArray(bid.userIdAsEids) || !bid.userIdAsEids.length) return; + + deepSetValue(postBody, 'user.eids', bid.userIdAsEids); +} + export function replaceUsersyncMacros(url, gdprConsent = {}, uspConsent = '', gppConsent = {}, type = '') { const { consentString = '', gdprApplies = false } = gdprConsent; const gdpr = Number(gdprApplies); @@ -391,7 +401,7 @@ function getAd(bid) { } else if (bid.nurl) { adUrl = bid.nurl; }; - } + }; return {ad, adUrl, vastXml, vastUrl}; } @@ -399,10 +409,21 @@ function getAd(bid) { function getSiteObj() { const refInfo = (getRefererInfo && getRefererInfo()) || {}; + let language = navigator.language; + let content; + if (language) { + // get ISO-639-1-alpha-2 (2 character language) + language = language.split('-')[0]; + content = { + language, + }; + }; + return { page: refInfo.page, ref: refInfo.ref, - domain: refInfo.domain + domain: refInfo.domain, + content, }; } @@ -410,6 +431,19 @@ function getDeviceObj() { return { w: window.innerWidth || window.document.documentElement.clientWidth || window.document.body.clientWidth || 0, h: window.innerHeight || window.document.documentElement.clientHeight || window.document.body.clientHeight || 0, + ua: window.navigator.userAgent || undefined, + sua: getSua(), + }; +} + +function getSua() { + let {brands, mobile, platform} = window?.navigator?.userAgentData; + if (!(brands && platform)) return undefined; + + return { + brands, + mobile: Number(!!mobile), + platform: (platform && {brand: platform}) || undefined, }; } diff --git a/test/spec/modules/nextMillenniumBidAdapter_spec.js b/test/spec/modules/nextMillenniumBidAdapter_spec.js index 8b512218d56..fc2b63e23b2 100644 --- a/test/spec/modules/nextMillenniumBidAdapter_spec.js +++ b/test/spec/modules/nextMillenniumBidAdapter_spec.js @@ -406,6 +406,78 @@ describe('nextMillenniumBidAdapterTests', () => { } }); + describe('function setEids', () => { + const dataTests = [ + { + title: 'site.pagecat, site.content.cat and site.content.language', + data: { + postBody: {}, + bid: { + userIdAsEids: undefined, + }, + }, + + expected: {}, + }, + + { + title: 'site.pagecat, site.content.cat and site.content.language', + data: { + postBody: {}, + bid: { + userIdAsEids: [], + }, + }, + + expected: {}, + }, + + { + title: 'site.pagecat, site.content.cat and site.content.language', + data: { + postBody: {}, + bid: { + userIdAsEids: [ + { + source: '33across.com', + uids: [{id: 'some-random-id-value', atype: 1}], + }, + + { + source: 'utiq.com', + uids: [{id: 'some-random-id-value', atype: 1}], + }, + ], + }, + }, + + expected: { + user: { + eids: [ + { + source: '33across.com', + uids: [{id: 'some-random-id-value', atype: 1}], + }, + + { + source: 'utiq.com', + uids: [{id: 'some-random-id-value', atype: 1}], + }, + ], + }, + }, + }, + ]; + + for (let { title, data, expected } of dataTests) { + it(title, () => { + const { postBody, bid } = data; + setEids(postBody, bid); + expect(postBody).to.deep.equal(expected); + }); + } + }); + const bidRequestData = [{ adUnitCode: 'test-div', bidId: 'bid1234', From ca85907ac859b41b72d5b7a38d9f4e9f0a443ce3 Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Mon, 11 Dec 2023 13:53:40 +0300 Subject: [PATCH 13/18] formatted --- test/spec/modules/nextMillenniumBidAdapter_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spec/modules/nextMillenniumBidAdapter_spec.js b/test/spec/modules/nextMillenniumBidAdapter_spec.js index fc2b63e23b2..5c5f7430748 100644 --- a/test/spec/modules/nextMillenniumBidAdapter_spec.js +++ b/test/spec/modules/nextMillenniumBidAdapter_spec.js @@ -403,7 +403,7 @@ describe('nextMillenniumBidAdapterTests', () => { setOrtb2Parameters(postBody, ortb2); expect(postBody).to.deep.equal(expected); }); - } + }; }); describe('function setEids', () => { From 6c1be2da75ff7fea04ce0ac2c6b2f20cb1aef4ce Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Mon, 11 Dec 2023 15:09:18 +0300 Subject: [PATCH 14/18] fixed tests --- test/spec/modules/nextMillenniumBidAdapter_spec.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/spec/modules/nextMillenniumBidAdapter_spec.js b/test/spec/modules/nextMillenniumBidAdapter_spec.js index 5c5f7430748..f57db82aedc 100644 --- a/test/spec/modules/nextMillenniumBidAdapter_spec.js +++ b/test/spec/modules/nextMillenniumBidAdapter_spec.js @@ -4,6 +4,7 @@ import { replaceUsersyncMacros, setConsentStrings, setOrtb2Parameters, + setEids, spec, } from 'modules/nextMillenniumBidAdapter.js'; @@ -409,7 +410,7 @@ describe('nextMillenniumBidAdapterTests', () => { describe('function setEids', () => { const dataTests = [ { - title: 'site.pagecat, site.content.cat and site.content.language', + title: 'setEids - userIdAsEids is empty', data: { postBody: {}, bid: { @@ -421,7 +422,7 @@ describe('nextMillenniumBidAdapterTests', () => { }, { - title: 'site.pagecat, site.content.cat and site.content.language', + title: 'setEids - userIdAsEids - array is empty', data: { postBody: {}, bid: { @@ -433,7 +434,7 @@ describe('nextMillenniumBidAdapterTests', () => { }, { - title: 'site.pagecat, site.content.cat and site.content.language', + title: 'setEids - userIdAsEids is', data: { postBody: {}, bid: { From 19b4db5f30d2e6af03c60d7b8efa5359b70b20dc Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Mon, 11 Dec 2023 15:29:04 +0300 Subject: [PATCH 15/18] fixed bug functio getSua --- modules/nextMillenniumBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index f1a806c29ae..5dea4f9b651 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -437,7 +437,7 @@ function getDeviceObj() { } function getSua() { - let {brands, mobile, platform} = window?.navigator?.userAgentData; + let {brands, mobile, platform} = (window?.navigator?.userAgentData || {}); if (!(brands && platform)) return undefined; return { From 957fa96059f2aa112067c9edcfd4a6f294a360c6 Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Sun, 25 Feb 2024 13:20:39 +0300 Subject: [PATCH 16/18] deleted deprecated code wurl --- modules/nextMillenniumBidAdapter.js | 55 ----------------------------- 1 file changed, 55 deletions(-) diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index d151523b265..58f65386e5f 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -8,7 +8,6 @@ import { getWindowTop, isArray, isStr, - logMessage, parseGPTSingleSizeArrayToRtbSize, parseUrl, triggerPixel, @@ -58,12 +57,6 @@ const ALLOWED_ORTB2_PARAMETERS = [ const sendingDataStatistic = initSendingDataStatistic(); events.on(CONSTANTS.EVENTS.AUCTION_INIT, auctionInitHandler); -const EXPIRENCE_WURL = 20 * 60000; -const wurlMap = {}; -cleanWurl(); - -events.on(CONSTANTS.EVENTS.BID_WON, bidWonHandler); - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO], @@ -148,11 +141,6 @@ export const spec = { _each(resp.bid, (bid) => { const requestId = bidRequest.bidId; const params = bidRequest.params; - const auctionId = bidRequest.auctionId; - const wurl = deepAccess(bid, 'ext.prebid.events.win'); - - // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781 - addWurl({auctionId, requestId, wurl}); const {ad, adUrl, vastUrl, vastXml} = getAd(bid); @@ -487,53 +475,10 @@ function getSua() { }; } -function getKeyWurl({auctionId, requestId}) { - return `${auctionId}-${requestId}`; -} - -function addWurl({wurl, requestId, auctionId}) { - if (!wurl) return; - - const expirence = Date.now() + EXPIRENCE_WURL; - const key = getKeyWurl({auctionId, requestId}); - wurlMap[key] = {wurl, expirence}; -} - -function removeWurl({auctionId, requestId}) { - const key = getKeyWurl({auctionId, requestId}); - delete wurlMap[key]; -} - -function getWurl({auctionId, requestId}) { - const key = getKeyWurl({auctionId, requestId}); - return wurlMap[key] && wurlMap[key].wurl; -} - -function bidWonHandler(bid) { - const {auctionId, requestId} = bid; - const wurl = getWurl({auctionId, requestId}); - if (wurl) { - logMessage(`(nextmillennium) Invoking image pixel for wurl on BID_WIN: "${wurl}"`); - triggerPixel(wurl); - removeWurl({auctionId, requestId}); - }; -} - function auctionInitHandler() { sendingDataStatistic.initEvents(); } -function cleanWurl() { - const dateNow = Date.now(); - Object.keys(wurlMap).forEach(key => { - if (dateNow >= wurlMap[key].expirence) { - delete wurlMap[key]; - }; - }); - - setTimeout(cleanWurl, 60000); -} - function initSendingDataStatistic() { class SendingDataStatistic { eventNames = [ From 8e89e866667617c742e116fb0aee54edffac503c Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Sun, 25 Feb 2024 17:29:22 +0300 Subject: [PATCH 17/18] removed the use of the events module --- modules/nextMillenniumBidAdapter.js | 105 ++++-------------- .../modules/nextMillenniumBidAdapter_spec.js | 2 +- 2 files changed, 22 insertions(+), 85 deletions(-) diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index 58f65386e5f..a137ce0aa4e 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -17,7 +17,6 @@ import {getGlobal} from '../src/prebidGlobal.js'; import CONSTANTS from '../src/constants.json'; import {BANNER, VIDEO} from '../src/mediaTypes.js'; import {config} from '../src/config.js'; -import * as events from '../src/events.js'; import {registerBidder} from '../src/adapters/bidderFactory.js'; import {getRefererInfo} from '../src/refererDetection.js'; @@ -54,9 +53,6 @@ const ALLOWED_ORTB2_PARAMETERS = [ 'user.keywords', ]; -const sendingDataStatistic = initSendingDataStatistic(); -events.on(CONSTANTS.EVENTS.AUCTION_INIT, auctionInitHandler); - export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO], @@ -72,7 +68,7 @@ export const spec = { const requests = []; window.nmmRefreshCounts = window.nmmRefreshCounts || {}; - _each(validBidRequests, function(bid) { + _each(validBidRequests, (bid) => { window.nmmRefreshCounts[bid.adUnitCode] = window.nmmRefreshCounts[bid.adUnitCode] || 0; const id = getPlacementId(bid); const auctionId = bid.auctionId; @@ -128,6 +124,8 @@ export const spec = { params, auctionId, }); + + this.getUrlPixelMetric(CONSTANTS.EVENTS.BID_REQUESTED, bid); }); return requests; @@ -170,6 +168,8 @@ export const spec = { }; bidResponses.push(bidResponse); + + this.getUrlPixelMetric(CONSTANTS.EVENTS.BID_RESPONSE, bid); }); }); @@ -203,6 +203,16 @@ export const spec = { }, getUrlPixelMetric(eventName, bid) { + const disabledSending = !!config.getBidderConfig()?.nextMillennium?.disabledSendingStatisticData; + if (disabledSending) return; + + const url = this._getUrlPixelMetric(eventName, bid); + if (!url) return; + + triggerPixel(url); + }, + + _getUrlPixelMetric(eventName, bid) { const bidder = bid.bidder || bid.bidderCode; if (bidder != BIDDER_CODE) return; @@ -236,6 +246,12 @@ export const spec = { return url; }, + + onTimeout(bids) { + for (const bid of bids) { + this.getUrlPixelMetric(CONSTANTS.EVENTS.BID_TIMEOUT, bid); + }; + }, }; export function getImp(bid, id, mediaTypes) { @@ -475,83 +491,4 @@ function getSua() { }; } -function auctionInitHandler() { - sendingDataStatistic.initEvents(); -} - -function initSendingDataStatistic() { - class SendingDataStatistic { - eventNames = [ - CONSTANTS.EVENTS.BID_TIMEOUT, - CONSTANTS.EVENTS.BID_RESPONSE, - CONSTANTS.EVENTS.BID_REQUESTED, - CONSTANTS.EVENTS.NO_BID, - ]; - - disabledSending = false; - enabledSending = false; - eventHendlers = {}; - - initEvents() { - this.disabledSending = !!config.getBidderConfig()?.nextMillennium?.disabledSendingStatisticData; - if (this.disabledSending) { - this.removeEvents(); - } else { - this.createEvents(); - }; - } - - createEvents() { - if (this.enabledSending) return; - - this.enabledSending = true; - for (let eventName of this.eventNames) { - if (!this.eventHendlers[eventName]) { - this.eventHendlers[eventName] = this.eventHandler(eventName); - }; - - events.on(eventName, this.eventHendlers[eventName]); - }; - } - - removeEvents() { - if (!this.enabledSending) return; - - this.enabledSending = false; - for (let eventName of this.eventNames) { - if (!this.eventHendlers[eventName]) continue; - - events.off(eventName, this.eventHendlers[eventName]); - }; - } - - eventHandler(eventName) { - const eventHandlerFunc = this.getEventHandler(eventName); - if (eventName == CONSTANTS.EVENTS.BID_TIMEOUT) { - return bids => { - if (this.disabledSending || !Array.isArray(bids)) return; - - for (let bid of bids) { - eventHandlerFunc(bid); - }; - } - }; - - return eventHandlerFunc; - } - - getEventHandler(eventName) { - return bid => { - if (this.disabledSending) return; - - const url = spec.getUrlPixelMetric(eventName, bid); - if (!url) return; - triggerPixel(url); - }; - } - }; - - return new SendingDataStatistic(); -} - registerBidder(spec); diff --git a/test/spec/modules/nextMillenniumBidAdapter_spec.js b/test/spec/modules/nextMillenniumBidAdapter_spec.js index b9871bbbe71..4f11c255803 100644 --- a/test/spec/modules/nextMillenniumBidAdapter_spec.js +++ b/test/spec/modules/nextMillenniumBidAdapter_spec.js @@ -902,7 +902,7 @@ describe('nextMillenniumBidAdapterTests', () => { ]; for (let {eventName, bid, expected} of dataForTests) { - const url = spec.getUrlPixelMetric(eventName, bid); + const url = spec._getUrlPixelMetric(eventName, bid); expect(url).to.equal(expected); }; }) From 38f644f578877f2b13de9a18ec75a3e76694df2a Mon Sep 17 00:00:00 2001 From: Mikhail Malkov Date: Wed, 28 Feb 2024 18:33:49 +0300 Subject: [PATCH 18/18] added parameters w and h for imp[].banner objecct --- modules/nextMillenniumBidAdapter.js | 6 +++++- test/spec/modules/nextMillenniumBidAdapter_spec.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index a137ce0aa4e..c64fb7b7ea4 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -271,8 +271,12 @@ export function getImp(bid, id, mediaTypes) { if (banner.bidfloorcur) imp.bidfloorcur = banner.bidfloorcur; if (banner.bidfloor) imp.bidfloor = banner.bidfloor; + const format = (banner.data?.sizes || []).map(s => { return {w: s[0], h: s[1]} }) + const {w, h} = (format[0] || {}) imp.banner = { - format: (banner.data?.sizes || []).map(s => { return {w: s[0], h: s[1]} }), + w, + h, + format, }; }; diff --git a/test/spec/modules/nextMillenniumBidAdapter_spec.js b/test/spec/modules/nextMillenniumBidAdapter_spec.js index 4f11c255803..6b7c559229b 100644 --- a/test/spec/modules/nextMillenniumBidAdapter_spec.js +++ b/test/spec/modules/nextMillenniumBidAdapter_spec.js @@ -34,7 +34,7 @@ describe('nextMillenniumBidAdapterTests', () => { bidfloorcur: 'EUR', bidfloor: 1.11, ext: {prebid: {storedrequest: {id: '123'}}}, - banner: {format: [{w: 300, h: 250}, {w: 320, h: 250}]}, + banner: {w: 300, h: 250, format: [{w: 300, h: 250}, {w: 320, h: 250}]}, }, },