From bf3af240a1b49cad6715de20ad6c92742e03f86b Mon Sep 17 00:00:00 2001 From: Hendrick Musche <107099114+sag-henmus@users.noreply.github.com> Date: Fri, 7 Jun 2024 03:43:58 +0200 Subject: [PATCH] SeedingAlliance Bid Adapter : get and set UUID and read EIDs where applicable (#11201) * add seedingAlliance Adapter * add two native default params * ... * ... * seedingAlliance Adapter: add two more default native params * updating seedingAlliance Adapter * seedingAlliance Adapter * Add UUID from LocalStorage * get eids and add nativendo first party id * Add Unit Tests for UUID and EIDs * fix minor lint error --------- Co-authored-by: Jonas Hilsen Co-authored-by: SeedingAllianceTech <55976067+SeedingAllianceTech@users.noreply.github.com> Co-authored-by: sag-jonhil <78849369+sag-jonhil@users.noreply.github.com> --- modules/seedingAllianceBidAdapter.js | 51 +++++++++++- .../modules/seedingAllianceAdapter_spec.js | 79 +++++++++++++++++++ 2 files changed, 128 insertions(+), 2 deletions(-) diff --git a/modules/seedingAllianceBidAdapter.js b/modules/seedingAllianceBidAdapter.js index e287ea7ff78..f998df27d5c 100755 --- a/modules/seedingAllianceBidAdapter.js +++ b/modules/seedingAllianceBidAdapter.js @@ -3,17 +3,21 @@ import {registerBidder} from '../src/adapters/bidderFactory.js'; import {BANNER, NATIVE} from '../src/mediaTypes.js'; -import {_map, deepSetValue, isArray, isEmpty, replaceAuctionPrice} from '../src/utils.js'; +import {_map, generateUUID, deepSetValue, isArray, isEmpty, replaceAuctionPrice} from '../src/utils.js'; import {config} from '../src/config.js'; import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; +import {getStorageManager} from '../src/storageManager.js'; const GVL_ID = 371; const BIDDER_CODE = 'seedingAlliance'; const DEFAULT_CUR = 'EUR'; const ENDPOINT_URL = 'https://b.nativendo.de/cds/rtb/bid?format=openrtb2.5&ssp=pb'; +const NATIVENDO_KEY = 'nativendo_id'; const NATIVE_ASSET_IDS = { 0: 'title', 1: 'body', 2: 'sponsoredBy', 3: 'image', 4: 'cta', 5: 'icon' }; +export const storage = getStorageManager({bidderCode: BIDDER_CODE}); + const NATIVE_PARAMS = { title: { id: 0, name: 'title' }, body: { id: 1, name: 'data', type: 2 }, @@ -37,6 +41,7 @@ export const spec = { validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests); let url = bidderRequest.refererInfo.page; + let eids = getEids(validBidRequests[0]); const imps = validBidRequests.map((bidRequest, id) => { const imp = { @@ -130,11 +135,14 @@ export const spec = { deepSetValue(request, 'user.ext.consent', bidderRequest.gdprConsent.consentString); deepSetValue(request, 'regs.ext.gdpr', (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean' && bidderRequest.gdprConsent.gdprApplies) ? 1 : 0); + deepSetValue(request, 'user.ext.eids', eids); } + let endpoint = config.getConfig('seedingAlliance.endpoint') || ENDPOINT_URL; + return { method: 'POST', - url: config.getConfig('seedingAlliance.endpoint') || ENDPOINT_URL, + url: endpoint, data: JSON.stringify(request), bidRequests: validBidRequests }; @@ -191,6 +199,45 @@ export const spec = { } }; +const getNativendoID = () => { + let nativendoID = storage.localStorageIsEnabled() && + storage.getDataFromLocalStorage(NATIVENDO_KEY); + + if (!nativendoID) { + if (storage.localStorageIsEnabled()) { + nativendoID = generateUUID(); + storage.setDataInLocalStorage(NATIVENDO_KEY, nativendoID); + } + } + + return nativendoID; +} + +const getEids = (bidRequest) => { + const eids = []; + const nativendoID = getNativendoID(); + + if (nativendoID) { + const nativendoUserEid = { + source: 'nativendo.de', + uids: [ + { + id: nativendoID, + atype: 1 + } + ] + }; + + eids.push(nativendoUserEid); + } + + if (bidRequest.userIdAsEids) { + eids.push(bidRequest.userIdAsEids); + } + + return eids; +} + function transformSizes(requestSizes) { if (!isArray(requestSizes)) { return []; diff --git a/test/spec/modules/seedingAllianceAdapter_spec.js b/test/spec/modules/seedingAllianceAdapter_spec.js index 03548cf923a..45d1544d100 100755 --- a/test/spec/modules/seedingAllianceAdapter_spec.js +++ b/test/spec/modules/seedingAllianceAdapter_spec.js @@ -1,5 +1,6 @@ // jshint esversion: 6, es3: false, node: true import {assert, expect} from 'chai'; +import {getStorageManager} from 'src/storageManager.js'; import {spec} from 'modules/seedingAllianceBidAdapter.js'; import { NATIVE } from 'src/mediaTypes.js'; import { config } from 'src/config.js'; @@ -100,6 +101,84 @@ describe('SeedingAlliance adapter', function () { }); }); + describe('check user ID functionality', function () { + let storage = getStorageManager({ bidderCode: 'seedingAlliance' }); + let localStorageIsEnabledStub = sinon.stub(storage, 'localStorageIsEnabled'); + let getDataFromLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); + const bidRequests = [{ + bidId: 'bidId', + params: {} + }]; + const bidderRequest = { + refererInfo: { referer: 'page' }, + gdprConsent: 'CP0j9IAP0j9IAAGABCENAYEgAP_gAAAAAAYgIxBVBCpNDWFAMHBVAJIgCYAU1sARIAQAABCAAyAFAAOA8IAA0QECEAQAAAACAAAAgVABAAAAAABEAACAAAAEAQFkAAQQgAAIAAAAAAEQQgBQAAgAAAAAEAAIgAABAwQAkACQIYLEBUCAhIAgCgAAAIgBgICAAgMACEAYAAAAAAIAAIBAAgIEMIAAAAECAQAAAFhIEoACAAKgAcgA-AEAAMgAaABEACYAG8APwAhIBDAESAJYATQAw4B9gH6ARQAjQBKQC5gF6AMUAbQA3ACdgFDgLzAYMAw0BmYDVwGsgOCAcmA8cCEMELQQuCAAgGQgQMHQKAAKgAcgA-AEAAMgAaABEACYAG8AP0AhgCJAEsAJoAYYA0YB9gH6ARQAiwBIgCUgFzAL0AYoA2gBuAEXgJkATsAocBeYDBgGGgMqAZYAzMBpoDVwHFgOTAeOBC0cAHAAQABcAKACEAF0AMEAZCQgFABMADeARQAlIBcwDFAG0AeOBCgCFpAAGAAgBggEMyUAwABAAHAAPgBEACZAIYAiQB-AFzAMUAi8BeYEISQAMAC4DLAIZlIEAAFQAOQAfACAAGQANAAiABMACkAH6AQwBEgDRgH4AfoBFgCRAEpALmAYoA2gBuAEXgJ2AUOAvMBhoDLAGsgOCAcmA8cCEIELQIZlAAoAFwB9gLoAYIBAwtADAL0AzMB44AAA.f_wAAAAAAAAA' + } + let request; + + before(function () { + storage.removeDataFromLocalStorage('nativendo_id'); + const localStorageData = { + nativendo_id: '123' + }; + + getDataFromLocalStorageStub.callsFake(function (key) { + return localStorageData[key]; + }); + }); + + it('should return an empty array if local storage is not enabled', function () { + localStorageIsEnabledStub.returns(false); + $$PREBID_GLOBAL$$.bidderSettings = { + seedingAlliance: { + storageAllowed: false + } + }; + + request = JSON.parse(spec.buildRequests(bidRequests, bidderRequest).data); + expect(request.user.ext.eids).to.be.an('array').that.is.empty; + }); + + it('should return an empty array if local storage is enabled but storageAllowed is false', function () { + $$PREBID_GLOBAL$$.bidderSettings = { + seedingAlliance: { + storageAllowed: false + } + }; + localStorageIsEnabledStub.returns(true); + + request = JSON.parse(spec.buildRequests(bidRequests, bidderRequest).data); + expect(request.user.ext.eids).to.be.an('array').that.is.empty; + }); + + it('should return a non empty array if local storage is enabled and storageAllowed is true', function () { + $$PREBID_GLOBAL$$.bidderSettings = { + seedingAlliance: { + storageAllowed: true + } + }; + localStorageIsEnabledStub.returns(true); + + request = JSON.parse(spec.buildRequests(bidRequests, bidderRequest).data); + expect(request.user.ext.eids).to.be.an('array').that.is.not.empty; + }); + + it('should return an array containing the nativendoUserEid', function () { + $$PREBID_GLOBAL$$.bidderSettings = { + seedingAlliance: { + storageAllowed: true + } + }; + localStorageIsEnabledStub.returns(true); + + let nativendoUserEid = { source: 'nativendo.de', uids: [{ id: '123', atype: 1 }] }; + storage.setDataInLocalStorage('nativendo_id', '123'); + + request = JSON.parse(spec.buildRequests(bidRequests, bidderRequest).data); + + expect(request.user.ext.eids).to.deep.include(nativendoUserEid); + }); + }); + describe('interpretResponse', function () { const goodNativeResponse = { body: {