From dd7399e6f08ba09776f102a14ee6e166adbc044c Mon Sep 17 00:00:00 2001 From: dlepetynskyi Date: Wed, 2 Oct 2024 15:32:22 +0300 Subject: [PATCH 01/21] update intentIqAnalyticsAdapter.js && intentIqIdSystem.js --- .../intentIqConstants/intentIqConstants.js | 11 +++++++ modules/intentIqAnalyticsAdapter.js | 12 ++++---- modules/intentIqIdSystem.js | 29 ++++++++++--------- .../modules/intentIqAnalyticsAdapter_spec.js | 1 + test/spec/modules/intentIqIdSystem_spec.js | 14 +++++++++ 5 files changed, 47 insertions(+), 20 deletions(-) create mode 100644 libraries/intentIqConstants/intentIqConstants.js diff --git a/libraries/intentIqConstants/intentIqConstants.js b/libraries/intentIqConstants/intentIqConstants.js new file mode 100644 index 00000000000..3590f1bc000 --- /dev/null +++ b/libraries/intentIqConstants/intentIqConstants.js @@ -0,0 +1,11 @@ +export const FIRST_PARTY_KEY = '_iiq_fdata'; +export let FIRST_PARTY_DATA_KEY = '_iiq_fdata'; + +export const WITH_IIQ = 'A'; +export const WITHOUT_IIQ = 'B'; +export const NOT_YET_DEFINED = 'U'; +export const OPT_OUT = 'O'; +export const BLACK_LIST = 'L'; +export const CLIENT_HINTS_KEY = '_iiq_ch'; +export const EMPTY = 'EMPTY' +export const VERSION = 0.21 diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index 76615730dd5..49d843223d9 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -7,6 +7,7 @@ import { config } from '../src/config.js'; import { EVENTS } from '../src/constants.js'; import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; import { detectBrowser } from '../libraries/detectBrowserUtils/detectBrowserUtils.js'; +import { FIRST_PARTY_KEY, FIRST_PARTY_DATA_KEY, VERSION } from '../libraries/intentIqConstants/intentIqConstants'; const MODULE_NAME = 'iiqAnalytics' const analyticsType = 'endpoint'; @@ -15,10 +16,6 @@ const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleNam const prebidVersion = '$prebid.version$'; export const REPORTER_ID = Date.now() + '_' + getRandom(0, 1000); -const FIRST_PARTY_KEY = '_iiq_fdata'; -const FIRST_PARTY_DATA_KEY = '_iiq_fdata'; -const JSVERSION = 0.2 - const PARAMS_NAMES = { abTestGroup: 'abGroup', pbPauseUntil: 'pbPauseUntil', @@ -158,6 +155,9 @@ function getRandom(start, end) { return Math.floor((Math.random() * (end - start + 1)) + start); } +const intentIqBidWon = {reportExternalWin: bidWon} +pbjs.intentIqBidWon = intentIqBidWon + export function preparePayload(data) { let result = getDefaultDataObject(); @@ -206,7 +206,7 @@ function getDefaultDataObject() { 'partnerAuctionId': 'BW', 'reportSource': 'pbjs', 'abGroup': 'U', - 'jsversion': JSVERSION, + 'jsversion': VERSION, 'partnerId': -1, 'biddingPlatformId': 1, 'idls': false, @@ -224,7 +224,7 @@ function constructFullUrl(data) { ((iiqAnalyticsAnalyticsAdapter.initOptions && iiqAnalyticsAnalyticsAdapter.initOptions.fpid) ? '&iiqid=' + encodeURIComponent(iiqAnalyticsAnalyticsAdapter.initOptions.fpid.pcid) : '') + '&agid=' + REPORTER_ID + - '&jsver=' + JSVERSION + + '&jsver=' + VERSION + '&vrref=' + getReferrer() + '&source=pbjs' + '&payload=' + JSON.stringify(report) diff --git a/modules/intentIqIdSystem.js b/modules/intentIqIdSystem.js index 2702aa9848d..ca299a8c224 100644 --- a/modules/intentIqIdSystem.js +++ b/modules/intentIqIdSystem.js @@ -14,6 +14,17 @@ import { gppDataHandler, uspDataHandler } from '../src/consentHandler.js'; import AES from 'crypto-js/aes.js'; import Utf8 from 'crypto-js/enc-utf8.js'; import { detectBrowser } from '../libraries/detectBrowserUtils/detectBrowserUtils.js'; +import { + FIRST_PARTY_KEY, + FIRST_PARTY_DATA_KEY, + WITH_IIQ, WITHOUT_IIQ, + NOT_YET_DEFINED, + OPT_OUT, + BLACK_LIST, + CLIENT_HINTS_KEY, + EMPTY, + VERSION +} from '../libraries/intentIqConstants/intentIqConstants'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -24,16 +35,6 @@ import { detectBrowser } from '../libraries/detectBrowserUtils/detectBrowserUtil const PCID_EXPIRY = 365; const MODULE_NAME = 'intentIqId'; -export const FIRST_PARTY_KEY = '_iiq_fdata'; -export let FIRST_PARTY_DATA_KEY = '_iiq_fdata'; -export const WITH_IIQ = 'A'; -export const WITHOUT_IIQ = 'B'; -export const NOT_YET_DEFINED = 'U'; -export const OPT_OUT = 'O'; -export const BLACK_LIST = 'L'; -export const CLIENT_HINTS_KEY = '_iiq_ch'; -export const EMPTY = 'EMPTY' -export const VERSION = 0.2 const encoderCH = { brands: 0, @@ -233,6 +234,10 @@ export const intentIqIdSubmodule = { let callbackFired = false let runtimeEids = {} + const allowedStorage = defineStorageType(config.enabledStorageTypes); + + let firstPartyData = tryParse(readData(FIRST_PARTY_KEY, allowedStorage)); + const firePartnerCallback = () => { if (configParams.callback && !callbackFired) { callbackFired = true; @@ -257,7 +262,6 @@ export const intentIqIdSubmodule = { const currentBrowserLowerCase = detectBrowser(); const browserBlackList = typeof configParams.browserBlackList === 'string' ? configParams.browserBlackList.toLowerCase() : ''; - const allowedStorage = defineStorageType(config.enabledStorageTypes); // Check if current browser is in blacklist if (browserBlackList?.includes(currentBrowserLowerCase)) { @@ -313,9 +317,6 @@ export const intentIqIdSubmodule = { FIRST_PARTY_DATA_KEY += '_' + configParams.partner; } - // Read Intent IQ 1st party id or generate it if none exists - let firstPartyData = tryParse(readData(FIRST_PARTY_KEY, allowedStorage)); - if (!firstPartyData?.pcid) { const firstPartyId = generateGUID(); firstPartyData = { pcid: firstPartyId, pcidDate: Date.now(), group: NOT_YET_DEFINED, cttl: 0, uspapi_value: EMPTY, gpp_value: EMPTY, date: Date.now() }; diff --git a/test/spec/modules/intentIqAnalyticsAdapter_spec.js b/test/spec/modules/intentIqAnalyticsAdapter_spec.js index 6c9a0fb9e79..71380736e1a 100644 --- a/test/spec/modules/intentIqAnalyticsAdapter_spec.js +++ b/test/spec/modules/intentIqAnalyticsAdapter_spec.js @@ -238,6 +238,7 @@ describe('IntentIQ tests all', function () { events.emit(EVENTS.BID_WON, wonRequest); expect(server.requests.length).to.be.above(0); + expect(pbjs.intentIqBidWon.bidWon).to.be.a('function'); const request = server.requests[0]; expect(request.url).to.contain(`https://reports.intentiq.com/report?pid=${partner}&mct=1`); expect(request.url).to.contain(`&jsver=${version}&vrref=http://localhost:9876/`); diff --git a/test/spec/modules/intentIqIdSystem_spec.js b/test/spec/modules/intentIqIdSystem_spec.js index 596185bedbd..4a5c58ce581 100644 --- a/test/spec/modules/intentIqIdSystem_spec.js +++ b/test/spec/modules/intentIqIdSystem_spec.js @@ -492,4 +492,18 @@ describe('IntentIQ tests', function () { const savedClientHints = readData(CLIENT_HINTS_KEY, ['html5']); expect(savedClientHints).to.equal(handleClientHints(testClientHints)); }); + + it('should get firstPartyData', async () => { + let wasCallbackCalled = false + const callbackConfigParams = { params: { partner: partner, + pai: pai, + pcid: pcid, + browserBlackList: 'Chrome', + callback: () => { + wasCallbackCalled = true + } } }; + + await intentIqIdSubmodule.getId(callbackConfigParams); + expect(wasCallbackCalled).to.equal(true); + }); }); From 9cf5ec0f57f0198b93eb4293b9339b185ead2145 Mon Sep 17 00:00:00 2001 From: DimaIntentIQ Date: Wed, 2 Oct 2024 15:39:03 +0300 Subject: [PATCH 02/21] fix lint issues --- modules/intentIqAnalyticsAdapter.js | 6 +++--- modules/intentIqIdSystem.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index 49d843223d9..233267acaa2 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -7,7 +7,7 @@ import { config } from '../src/config.js'; import { EVENTS } from '../src/constants.js'; import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; import { detectBrowser } from '../libraries/detectBrowserUtils/detectBrowserUtils.js'; -import { FIRST_PARTY_KEY, FIRST_PARTY_DATA_KEY, VERSION } from '../libraries/intentIqConstants/intentIqConstants'; +import { FIRST_PARTY_KEY, FIRST_PARTY_DATA_KEY, VERSION } from '../libraries/intentIqConstants/intentIqConstants.js'; const MODULE_NAME = 'iiqAnalytics' const analyticsType = 'endpoint'; @@ -155,8 +155,8 @@ function getRandom(start, end) { return Math.floor((Math.random() * (end - start + 1)) + start); } -const intentIqBidWon = {reportExternalWin: bidWon} -pbjs.intentIqBidWon = intentIqBidWon +const intentIqBidWon = { reportExternalWin: bidWon } +window.pbjs.intentIqBidWon = intentIqBidWon export function preparePayload(data) { let result = getDefaultDataObject(); diff --git a/modules/intentIqIdSystem.js b/modules/intentIqIdSystem.js index ca299a8c224..c1194bd903e 100644 --- a/modules/intentIqIdSystem.js +++ b/modules/intentIqIdSystem.js @@ -24,7 +24,7 @@ import { CLIENT_HINTS_KEY, EMPTY, VERSION -} from '../libraries/intentIqConstants/intentIqConstants'; +} from '../libraries/intentIqConstants/intentIqConstants.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule From b0baad3c33c98b3e0127e05c04d3c9a67934fa85 Mon Sep 17 00:00:00 2001 From: dlepetynskyi Date: Wed, 2 Oct 2024 17:21:35 +0300 Subject: [PATCH 03/21] fix tests --- .../intentIqConstants/intentIqConstants.js | 1 - modules/intentIqAnalyticsAdapter.js | 9 +++++---- modules/intentIqIdSystem.js | 8 +++----- .../modules/intentIqAnalyticsAdapter_spec.js | 18 ++++++++++-------- test/spec/modules/intentIqIdSystem_spec.js | 3 ++- 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/libraries/intentIqConstants/intentIqConstants.js b/libraries/intentIqConstants/intentIqConstants.js index 3590f1bc000..46c466e936f 100644 --- a/libraries/intentIqConstants/intentIqConstants.js +++ b/libraries/intentIqConstants/intentIqConstants.js @@ -1,5 +1,4 @@ export const FIRST_PARTY_KEY = '_iiq_fdata'; -export let FIRST_PARTY_DATA_KEY = '_iiq_fdata'; export const WITH_IIQ = 'A'; export const WITHOUT_IIQ = 'B'; diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index 233267acaa2..46019a9c41d 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -7,7 +7,7 @@ import { config } from '../src/config.js'; import { EVENTS } from '../src/constants.js'; import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; import { detectBrowser } from '../libraries/detectBrowserUtils/detectBrowserUtils.js'; -import { FIRST_PARTY_KEY, FIRST_PARTY_DATA_KEY, VERSION } from '../libraries/intentIqConstants/intentIqConstants.js'; +import { FIRST_PARTY_KEY, VERSION } from '../libraries/intentIqConstants/intentIqConstants.js'; const MODULE_NAME = 'iiqAnalytics' const analyticsType = 'endpoint'; @@ -120,7 +120,7 @@ function initReadLsIds() { if (iiqAnalyticsAnalyticsAdapter.initOptions.fpid) { iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup = iiqAnalyticsAnalyticsAdapter.initOptions.fpid.group; } - let iData = readData(FIRST_PARTY_DATA_KEY + '_' + iiqAnalyticsAnalyticsAdapter.initOptions.partner); + let iData = readData(FIRST_PARTY_KEY + '_' + iiqAnalyticsAnalyticsAdapter.initOptions.partner); if (iData) { iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized = true; let pData = JSON.parse(iData); @@ -146,6 +146,7 @@ function bidWon(args) { if (iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized && !iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized) { initReadLsIds(); } if (!iiqAnalyticsAnalyticsAdapter.initOptions.manualReport) { ajax(constructFullUrl(preparePayload(args, true)), undefined, null, { method: 'GET' }); + return true } logInfo('IIQ ANALYTICS -> BID WON') @@ -233,9 +234,9 @@ function constructFullUrl(data) { export function getReferrer() { try { if (getWindowSelf() === getWindowTop()) { - return getWindowLocation().href; + return encodeURIComponent(getWindowLocation().href); } else { - return getWindowTop().location.href; + return encodeURIComponent(getWindowTop().location.href); } } catch (error) { logError(`Error accessing location: ${error}`); diff --git a/modules/intentIqIdSystem.js b/modules/intentIqIdSystem.js index c1194bd903e..222a36d16a4 100644 --- a/modules/intentIqIdSystem.js +++ b/modules/intentIqIdSystem.js @@ -16,7 +16,6 @@ import Utf8 from 'crypto-js/enc-utf8.js'; import { detectBrowser } from '../libraries/detectBrowserUtils/detectBrowserUtils.js'; import { FIRST_PARTY_KEY, - FIRST_PARTY_DATA_KEY, WITH_IIQ, WITHOUT_IIQ, NOT_YET_DEFINED, OPT_OUT, @@ -256,6 +255,9 @@ export const intentIqIdSubmodule = { firePartnerCallback() return; } + + const FIRST_PARTY_DATA_KEY = `_iiq_fdata_${configParams.partner}`; + let rrttStrtTime = 0; let partnerData = {}; let shouldCallServer = false @@ -313,10 +315,6 @@ export const intentIqIdSubmodule = { }); } - if (!FIRST_PARTY_DATA_KEY.includes(configParams.partner)) { - FIRST_PARTY_DATA_KEY += '_' + configParams.partner; - } - if (!firstPartyData?.pcid) { const firstPartyId = generateGUID(); firstPartyData = { pcid: firstPartyId, pcidDate: Date.now(), group: NOT_YET_DEFINED, cttl: 0, uspapi_value: EMPTY, gpp_value: EMPTY, date: Date.now() }; diff --git a/test/spec/modules/intentIqAnalyticsAdapter_spec.js b/test/spec/modules/intentIqAnalyticsAdapter_spec.js index 71380736e1a..5008ff431db 100644 --- a/test/spec/modules/intentIqAnalyticsAdapter_spec.js +++ b/test/spec/modules/intentIqAnalyticsAdapter_spec.js @@ -8,12 +8,12 @@ import { EVENTS } from 'src/constants.js'; import * as events from 'src/events.js'; import { getStorageManager } from 'src/storageManager.js'; import sinon from 'sinon'; -import { FIRST_PARTY_KEY } from '../../../modules/intentIqIdSystem'; import { REPORTER_ID, getReferrer, preparePayload } from '../../../modules/intentIqAnalyticsAdapter'; +import {FIRST_PARTY_KEY, VERSION} from '../../../libraries/intentIqConstants/intentIqConstants.js'; const partner = 10; const defaultData = '{"pcid":"f961ffb1-a0e1-4696-a9d2-a21d815bd344", "group": "A"}'; -const version = 0.2; +const version = VERSION; const storage = getStorageManager({ moduleType: 'analytics', moduleName: 'iiqAnalytics' }); @@ -121,7 +121,7 @@ describe('IntentIQ tests all', function () { expect(server.requests.length).to.be.above(0); const request = server.requests[0]; expect(request.url).to.contain('https://reports.intentiq.com/report?pid=' + partner + '&mct=1'); - expect(request.url).to.contain(`&jsver=${version}&vrref=http://localhost:9876/`); + expect(request.url).to.contain(`&jsver=${version}&vrref=${encodeURIComponent('http://localhost:9876/')}`); expect(request.url).to.contain('&payload='); expect(request.url).to.contain('iiqid=f961ffb1-a0e1-4696-a9d2-a21d815bd344'); }); @@ -138,7 +138,7 @@ describe('IntentIQ tests all', function () { expect(server.requests.length).to.be.above(0); const request = server.requests[0]; expect(request.url).to.contain('https://reports.intentiq.com/report?pid=' + partner + '&mct=1'); - expect(request.url).to.contain(`&jsver=${version}&vrref=http://localhost:9876/`); + expect(request.url).to.contain(`&jsver=${version}&vrref=${encodeURIComponent('http://localhost:9876/')}`); expect(request.url).to.contain('iiqid=testpcid'); }); @@ -180,6 +180,8 @@ describe('IntentIQ tests all', function () { events.emit(EVENTS.BID_WON, wonRequest); expect(iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup).to.equal('B'); expect(iiqAnalyticsAnalyticsAdapter.initOptions.fpid).to.be.not.null; + expect(window.pbjs.intentIqBidWon.reportExternalWin).to.be.a('function'); + expect(window.pbjs.intentIqBidWon.reportExternalWin({cpm: 1, currency: 'USD'})).to.equal(true); }); it('should return window.location.href when window.self === window.top', function () { @@ -189,7 +191,7 @@ describe('IntentIQ tests all', function () { getWindowLocationStub = sinon.stub(utils, 'getWindowLocation').returns({ href: 'http://localhost:9876/' }); const referrer = getReferrer(); - expect(referrer).to.equal('http://localhost:9876/'); + expect(referrer).to.equal(encodeURIComponent('http://localhost:9876/')); }); it('should return window.top.location.href when window.self !== window.top and access is successful', function () { @@ -198,7 +200,8 @@ describe('IntentIQ tests all', function () { getWindowTopStub = sinon.stub(utils, 'getWindowTop').returns({ location: { href: 'http://example.com/' } }); const referrer = getReferrer(); - expect(referrer).to.equal('http://example.com/'); + + expect(referrer).to.equal(encodeURIComponent('http://example.com/')); }); it('should return an empty string and log an error when accessing window.top.location.href throws an error', function () { @@ -238,10 +241,9 @@ describe('IntentIQ tests all', function () { events.emit(EVENTS.BID_WON, wonRequest); expect(server.requests.length).to.be.above(0); - expect(pbjs.intentIqBidWon.bidWon).to.be.a('function'); const request = server.requests[0]; expect(request.url).to.contain(`https://reports.intentiq.com/report?pid=${partner}&mct=1`); - expect(request.url).to.contain(`&jsver=${version}&vrref=http://localhost:9876/`); + expect(request.url).to.contain(`&jsver=${version}&vrref=${encodeURIComponent('http://localhost:9876/')}`); expect(request.url).to.contain('&payload='); expect(request.url).to.contain('iiqid=f961ffb1-a0e1-4696-a9d2-a21d815bd344'); }); diff --git a/test/spec/modules/intentIqIdSystem_spec.js b/test/spec/modules/intentIqIdSystem_spec.js index 4a5c58ce581..679a6ca19d4 100644 --- a/test/spec/modules/intentIqIdSystem_spec.js +++ b/test/spec/modules/intentIqIdSystem_spec.js @@ -2,10 +2,11 @@ import { expect } from 'chai'; import { intentIqIdSubmodule, storage } from 'modules/intentIqIdSystem.js'; import * as utils from 'src/utils.js'; import { server } from 'test/mocks/xhr.js'; -import { CLIENT_HINTS_KEY, FIRST_PARTY_KEY, decryptData, handleClientHints, handleGPPData, readData } from '../../../modules/intentIqIdSystem'; +import { decryptData, handleClientHints, handleGPPData, readData } from '../../../modules/intentIqIdSystem'; import { gppDataHandler, uspDataHandler } from '../../../src/consentHandler'; import { clearAllCookies } from '../../helpers/cookies'; import { detectBrowserFromUserAgent, detectBrowserFromUserAgentData } from '../../../libraries/detectBrowserUtils/detectBrowserUtils'; +import {CLIENT_HINTS_KEY, FIRST_PARTY_KEY} from '../../../libraries/intentIqConstants/intentIqConstants.js'; const partner = 10; const pai = '11'; From bfe0b15b0e89aa28ea11efac8dd06a097032abbb Mon Sep 17 00:00:00 2001 From: dlepetynskyi Date: Wed, 2 Oct 2024 17:25:46 +0300 Subject: [PATCH 04/21] move info --- modules/intentIqAnalyticsAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index 46019a9c41d..df8c2794759 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -146,10 +146,10 @@ function bidWon(args) { if (iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized && !iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized) { initReadLsIds(); } if (!iiqAnalyticsAnalyticsAdapter.initOptions.manualReport) { ajax(constructFullUrl(preparePayload(args, true)), undefined, null, { method: 'GET' }); + logInfo('IIQ ANALYTICS -> BID WON') return true } - logInfo('IIQ ANALYTICS -> BID WON') } function getRandom(start, end) { From c2406daf3ce40ac3485d789d969454fb403bfcdd Mon Sep 17 00:00:00 2001 From: dlepetynskyi Date: Mon, 7 Oct 2024 01:45:43 +0300 Subject: [PATCH 05/21] resolve issues --- modules/intentIqAnalyticsAdapter.js | 17 ++++++++++------- .../modules/intentIqAnalyticsAdapter_spec.js | 10 ++++++++-- test/spec/modules/intentIqIdSystem_spec.js | 2 +- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index df8c2794759..4a902b5b259 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -132,7 +132,7 @@ function initReadLsIds() { } } -function bidWon(args) { +function bidWon(args, isReportExternal) { if (!iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized) { initLsValues(); } if (isNaN(iiqAnalyticsAnalyticsAdapter.initOptions.partner) || iiqAnalyticsAnalyticsAdapter.initOptions.partner == -1) return; @@ -144,20 +144,23 @@ function bidWon(args) { } if (iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized && !iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized) { initReadLsIds(); } - if (!iiqAnalyticsAnalyticsAdapter.initOptions.manualReport) { - ajax(constructFullUrl(preparePayload(args, true)), undefined, null, { method: 'GET' }); + if ((isReportExternal && iiqAnalyticsAnalyticsAdapter.initOptions.manualReport) || (!isReportExternal && !iiqAnalyticsAnalyticsAdapter.initOptions.manualReport)) { + ajax(constructFullUrl(preparePayload(args, true)), undefined, null, {method: 'GET'}); logInfo('IIQ ANALYTICS -> BID WON') - return true + return true; } - } function getRandom(start, end) { return Math.floor((Math.random() * (end - start + 1)) + start); } -const intentIqBidWon = { reportExternalWin: bidWon } -window.pbjs.intentIqBidWon = intentIqBidWon +function reportExternalWin(args) { + return bidWon(args, true) +} + +const intentIqBidWon = { reportExternalWin: reportExternalWin } +window.intentIqAnalyticsAdapter = intentIqBidWon export function preparePayload(data) { let result = getDefaultDataObject(); diff --git a/test/spec/modules/intentIqAnalyticsAdapter_spec.js b/test/spec/modules/intentIqAnalyticsAdapter_spec.js index 5008ff431db..471e07aedb0 100644 --- a/test/spec/modules/intentIqAnalyticsAdapter_spec.js +++ b/test/spec/modules/intentIqAnalyticsAdapter_spec.js @@ -180,8 +180,14 @@ describe('IntentIQ tests all', function () { events.emit(EVENTS.BID_WON, wonRequest); expect(iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup).to.equal('B'); expect(iiqAnalyticsAnalyticsAdapter.initOptions.fpid).to.be.not.null; - expect(window.pbjs.intentIqBidWon.reportExternalWin).to.be.a('function'); - expect(window.pbjs.intentIqBidWon.reportExternalWin({cpm: 1, currency: 'USD'})).to.equal(true); + }); + + it('should handle reportExternalWin', function () { + iiqAnalyticsAnalyticsAdapter.initOptions.manualReport = true; + localStorage.setItem(FIRST_PARTY_KEY, '{"pcid":"testpcid", "group": "B"}'); + localStorage.setItem(FIRST_PARTY_KEY + '_' + partner, '{"data":"testpcid"}'); + expect(window.intentIqAnalyticsAdapter.reportExternalWin).to.be.a('function'); + expect(window.intentIqAnalyticsAdapter.reportExternalWin({cpm: 1, currency: 'USD'})).to.equal(true); }); it('should return window.location.href when window.self === window.top', function () { diff --git a/test/spec/modules/intentIqIdSystem_spec.js b/test/spec/modules/intentIqIdSystem_spec.js index 679a6ca19d4..a7ea6f76263 100644 --- a/test/spec/modules/intentIqIdSystem_spec.js +++ b/test/spec/modules/intentIqIdSystem_spec.js @@ -494,7 +494,7 @@ describe('IntentIQ tests', function () { expect(savedClientHints).to.equal(handleClientHints(testClientHints)); }); - it('should get firstPartyData', async () => { + it('should run callback from params', async () => { let wasCallbackCalled = false const callbackConfigParams = { params: { partner: partner, pai: pai, From 51240128c9cd89e68dc491d55a1a48442086ac29 Mon Sep 17 00:00:00 2001 From: dlepetynskyi Date: Wed, 9 Oct 2024 13:57:22 +0300 Subject: [PATCH 06/21] update storeFirstPartyData --- modules/intentIqAnalyticsAdapter.js | 29 ++++++++++++++++++++++------- modules/intentIqIdSystem.js | 29 +++++++++++++++-------------- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index 4a902b5b259..8892c7f7a56 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -16,6 +16,19 @@ const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleNam const prebidVersion = '$prebid.version$'; export const REPORTER_ID = Date.now() + '_' + getRandom(0, 1000); +/** + * Parse json if possible, else return null + * @param data + */ +function tryParse(data) { + try { + return JSON.parse(data); + } catch (err) { + logError(err); + return null; + } +} + const PARAMS_NAMES = { abTestGroup: 'abGroup', pbPauseUntil: 'pbPauseUntil', @@ -61,7 +74,7 @@ let iiqAnalyticsAnalyticsAdapter = Object.assign(adapter({ defaultUrl, analytics dataInLs: null, eidl: null, lsIdsInitialized: false, - manualReport: false + manualWinReportEnabled: false }, track({ eventType, args }) { switch (eventType) { @@ -120,10 +133,11 @@ function initReadLsIds() { if (iiqAnalyticsAnalyticsAdapter.initOptions.fpid) { iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup = iiqAnalyticsAnalyticsAdapter.initOptions.fpid.group; } - let iData = readData(FIRST_PARTY_KEY + '_' + iiqAnalyticsAnalyticsAdapter.initOptions.partner); - if (iData) { + let partnerData = readData(FIRST_PARTY_KEY + '_' + iiqAnalyticsAnalyticsAdapter.initOptions.partner); + if (partnerData) { iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized = true; - let pData = JSON.parse(iData); + let pData = JSON.parse(partnerData); + iiqAnalyticsAnalyticsAdapter.initOptions.terminationCause = pData.terminationCause iiqAnalyticsAnalyticsAdapter.initOptions.dataInLs = pData.data; iiqAnalyticsAnalyticsAdapter.initOptions.eidl = pData.eidl || -1; } @@ -144,7 +158,7 @@ function bidWon(args, isReportExternal) { } if (iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized && !iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized) { initReadLsIds(); } - if ((isReportExternal && iiqAnalyticsAnalyticsAdapter.initOptions.manualReport) || (!isReportExternal && !iiqAnalyticsAnalyticsAdapter.initOptions.manualReport)) { + if ((isReportExternal && iiqAnalyticsAnalyticsAdapter.initOptions.manualWinReportEnabled) || (!isReportExternal && !iiqAnalyticsAnalyticsAdapter.initOptions.manualWinReportEnabled)) { ajax(constructFullUrl(preparePayload(args, true)), undefined, null, {method: 'GET'}); logInfo('IIQ ANALYTICS -> BID WON') return true; @@ -164,11 +178,12 @@ window.intentIqAnalyticsAdapter = intentIqBidWon export function preparePayload(data) { let result = getDefaultDataObject(); - + let firstPartyData = tryParse(readData(FIRST_PARTY_KEY, allowedStorage)); + readData(FIRST_PARTY_KEY + '_' + iiqAnalyticsAnalyticsAdapter.initOptions.partner); result[PARAMS_NAMES.partnerId] = iiqAnalyticsAnalyticsAdapter.initOptions.partner; result[PARAMS_NAMES.prebidVersion] = prebidVersion; result[PARAMS_NAMES.referrer] = getReferrer(); - + result[PARAMS_NAMES.terminationCause] = iiqAnalyticsAnalyticsAdapter.initOptions.terminationCause; result[PARAMS_NAMES.abTestGroup] = iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup; result[PARAMS_NAMES.isInTestGroup] = iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup == 'A'; diff --git a/modules/intentIqIdSystem.js b/modules/intentIqIdSystem.js index 222a36d16a4..36baaa214b2 100644 --- a/modules/intentIqIdSystem.js +++ b/modules/intentIqIdSystem.js @@ -253,7 +253,7 @@ export const intentIqIdSubmodule = { if (typeof configParams.partner !== 'number') { logError('User ID - intentIqId submodule requires a valid partner to be defined'); firePartnerCallback() - return; + return {}; } const FIRST_PARTY_DATA_KEY = `_iiq_fdata_${configParams.partner}`; @@ -269,7 +269,7 @@ export const intentIqIdSubmodule = { if (browserBlackList?.includes(currentBrowserLowerCase)) { logError('User ID - intentIqId submodule: browser is in blacklist!'); if (configParams.callback) configParams.callback('', BLACK_LIST); - return; + return {}; } // Get consent information @@ -343,19 +343,20 @@ export const intentIqIdSubmodule = { firstPartyData.cttl = 0 shouldCallServer = true; partnerData.data = {} + partnerData.eidl = -1 storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); storeData(FIRST_PARTY_DATA_KEY, JSON.stringify(partnerData), allowedStorage); } else if (firstPartyData.isOptedOut) { firePartnerCallback() } - if (firstPartyData.group === WITHOUT_IIQ || (firstPartyData.group !== WITHOUT_IIQ && runtimeEids && Object.keys(runtimeEids).length)) { + if (firstPartyData.group === WITHOUT_IIQ || (firstPartyData.group !== WITHOUT_IIQ && runtimeEids?.eids?.length)) { firePartnerCallback() } if (!shouldCallServer) { firePartnerCallback(); - return { id: runtimeEids }; + return { id: runtimeEids?.eids || [] }; } // use protocol relative urls for http or https @@ -375,6 +376,7 @@ export const intentIqIdSubmodule = { url += firstPartyData?.group ? '&testGroup=' + encodeURIComponent(firstPartyData.group) : ''; const storeFirstPartyData = () => { + partnerData.eidl = runtimeEids?.eids?.length || -1 storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); storeData(FIRST_PARTY_DATA_KEY, JSON.stringify(partnerData), allowedStorage); } @@ -389,9 +391,11 @@ export const intentIqIdSubmodule = { firstPartyData.date = Date.now(); const defineEmptyDataAndFireCallback = () => { respJson.data = partnerData.data = runtimeEids = {}; - removeDataByKey(FIRST_PARTY_DATA_KEY, allowedStorage) + partnerData.data = '' + storeFirstPartyData() firePartnerCallback() callback() + return {} } if (callbackTimeoutID) clearTimeout(callbackTimeoutID) if ('cttl' in respJson) { @@ -403,8 +407,7 @@ export const intentIqIdSubmodule = { if (respJson.tc == 41) { firstPartyData.group = WITHOUT_IIQ; storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); - defineEmptyDataAndFireCallback(); - return; + return defineEmptyDataAndFireCallback(); } else { firstPartyData.group = WITH_IIQ; } @@ -416,8 +419,7 @@ export const intentIqIdSubmodule = { if (respJson.isOptedOut === true) { firstPartyData.group = OPT_OUT; storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); - defineEmptyDataAndFireCallback() - return; + return defineEmptyDataAndFireCallback() } } if ('pid' in respJson) { @@ -425,8 +427,7 @@ export const intentIqIdSubmodule = { } if ('ls' in respJson) { if (respJson.ls === false) { - defineEmptyDataAndFireCallback(); - return + return defineEmptyDataAndFireCallback() } // If data is empty, means we should save as INVALID_ID if (respJson.data == '') { @@ -445,10 +446,10 @@ export const intentIqIdSubmodule = { } if (respJson.data?.eids) { - runtimeEids = respJson.data.eids + runtimeEids = respJson.data callback(respJson.data.eids); firePartnerCallback() - const encryptedData = encryptData(JSON.stringify(respJson.data.eids)) + const encryptedData = encryptData(JSON.stringify(respJson.data)) partnerData.data = encryptedData; } else { callback(); @@ -469,7 +470,7 @@ export const intentIqIdSubmodule = { ajax(url, callbacks, undefined, { method: 'GET', withCredentials: true }); }; const respObj = { callback: resp }; - if (runtimeEids?.length) respObj.id = runtimeEids; + if (runtimeEids?.eids?.length) respObj.id = runtimeEids.eids; return respObj }, eids: { From 7d07e3b18e0d6bb33ca3eda723c852c66ebc4380 Mon Sep 17 00:00:00 2001 From: DimaIntentIQ Date: Wed, 9 Oct 2024 14:05:14 +0300 Subject: [PATCH 07/21] remove unused code --- modules/intentIqAnalyticsAdapter.js | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index 8892c7f7a56..ca3c06ab9c1 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -16,19 +16,6 @@ const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleNam const prebidVersion = '$prebid.version$'; export const REPORTER_ID = Date.now() + '_' + getRandom(0, 1000); -/** - * Parse json if possible, else return null - * @param data - */ -function tryParse(data) { - try { - return JSON.parse(data); - } catch (err) { - logError(err); - return null; - } -} - const PARAMS_NAMES = { abTestGroup: 'abGroup', pbPauseUntil: 'pbPauseUntil', @@ -178,7 +165,6 @@ window.intentIqAnalyticsAdapter = intentIqBidWon export function preparePayload(data) { let result = getDefaultDataObject(); - let firstPartyData = tryParse(readData(FIRST_PARTY_KEY, allowedStorage)); readData(FIRST_PARTY_KEY + '_' + iiqAnalyticsAnalyticsAdapter.initOptions.partner); result[PARAMS_NAMES.partnerId] = iiqAnalyticsAnalyticsAdapter.initOptions.partner; result[PARAMS_NAMES.prebidVersion] = prebidVersion; From dace56426764dd5dfc5cd0f815a724b355755ad8 Mon Sep 17 00:00:00 2001 From: dlepetynskyi Date: Wed, 9 Oct 2024 15:39:33 +0300 Subject: [PATCH 08/21] update defineEmptyDataAndFireCallback --- modules/intentIqAnalyticsAdapter.js | 13 ++++++++++--- modules/intentIqIdSystem.js | 18 +++++++++++------- src/events.js | 1 + .../modules/intentIqAnalyticsAdapter_spec.js | 8 ++++---- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index ca3c06ab9c1..8386a97b2db 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -7,7 +7,7 @@ import { config } from '../src/config.js'; import { EVENTS } from '../src/constants.js'; import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; import { detectBrowser } from '../libraries/detectBrowserUtils/detectBrowserUtils.js'; -import { FIRST_PARTY_KEY, VERSION } from '../libraries/intentIqConstants/intentIqConstants.js'; +import {CLIENT_HINTS_KEY, FIRST_PARTY_KEY, VERSION} from '../libraries/intentIqConstants/intentIqConstants.js'; const MODULE_NAME = 'iiqAnalytics' const analyticsType = 'endpoint'; @@ -110,6 +110,7 @@ function initLsValues() { iiqAnalyticsAnalyticsAdapter.initOptions.partner = iiqArr[0].params.partner; } iiqAnalyticsAnalyticsAdapter.initOptions.browserBlackList = typeof iiqArr[0].params.browserBlackList === 'string' ? iiqArr[0].params.browserBlackList.toLowerCase() : ''; + iiqAnalyticsAnalyticsAdapter.initOptions.manualWinReportEnabled = iiqArr[0].params.manualWinReportEnabled || false } } @@ -120,7 +121,10 @@ function initReadLsIds() { if (iiqAnalyticsAnalyticsAdapter.initOptions.fpid) { iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup = iiqAnalyticsAnalyticsAdapter.initOptions.fpid.group; } - let partnerData = readData(FIRST_PARTY_KEY + '_' + iiqAnalyticsAnalyticsAdapter.initOptions.partner); + const partnerData = readData(FIRST_PARTY_KEY + '_' + iiqAnalyticsAnalyticsAdapter.initOptions.partner); + const clientsHints = readData(CLIENT_HINTS_KEY) || ''; + + if (partnerData) { iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized = true; let pData = JSON.parse(partnerData); @@ -128,6 +132,8 @@ function initReadLsIds() { iiqAnalyticsAnalyticsAdapter.initOptions.dataInLs = pData.data; iiqAnalyticsAnalyticsAdapter.initOptions.eidl = pData.eidl || -1; } + + iiqAnalyticsAnalyticsAdapter.initOptions.clientsHints = clientsHints } catch (e) { logError(e) } @@ -232,7 +238,8 @@ function constructFullUrl(data) { '&jsver=' + VERSION + '&vrref=' + getReferrer() + '&source=pbjs' + - '&payload=' + JSON.stringify(report) + '&payload=' + JSON.stringify(report) + + '&uh=' + iiqAnalyticsAnalyticsAdapter.initOptions.clientsHints } export function getReferrer() { diff --git a/modules/intentIqIdSystem.js b/modules/intentIqIdSystem.js index 36baaa214b2..895b580de8f 100644 --- a/modules/intentIqIdSystem.js +++ b/modules/intentIqIdSystem.js @@ -253,7 +253,7 @@ export const intentIqIdSubmodule = { if (typeof configParams.partner !== 'number') { logError('User ID - intentIqId submodule requires a valid partner to be defined'); firePartnerCallback() - return {}; + return; } const FIRST_PARTY_DATA_KEY = `_iiq_fdata_${configParams.partner}`; @@ -269,7 +269,7 @@ export const intentIqIdSubmodule = { if (browserBlackList?.includes(currentBrowserLowerCase)) { logError('User ID - intentIqId submodule: browser is in blacklist!'); if (configParams.callback) configParams.callback('', BLACK_LIST); - return {}; + return; } // Get consent information @@ -394,8 +394,6 @@ export const intentIqIdSubmodule = { partnerData.data = '' storeFirstPartyData() firePartnerCallback() - callback() - return {} } if (callbackTimeoutID) clearTimeout(callbackTimeoutID) if ('cttl' in respJson) { @@ -407,7 +405,9 @@ export const intentIqIdSubmodule = { if (respJson.tc == 41) { firstPartyData.group = WITHOUT_IIQ; storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); - return defineEmptyDataAndFireCallback(); + defineEmptyDataAndFireCallback(); + callback({}) + return } else { firstPartyData.group = WITH_IIQ; } @@ -419,7 +419,9 @@ export const intentIqIdSubmodule = { if (respJson.isOptedOut === true) { firstPartyData.group = OPT_OUT; storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); - return defineEmptyDataAndFireCallback() + defineEmptyDataAndFireCallback() + callback({}) + return } } if ('pid' in respJson) { @@ -427,7 +429,9 @@ export const intentIqIdSubmodule = { } if ('ls' in respJson) { if (respJson.ls === false) { - return defineEmptyDataAndFireCallback() + defineEmptyDataAndFireCallback() + callback({}) + return } // If data is empty, means we should save as INVALID_ID if (respJson.data == '') { diff --git a/src/events.js b/src/events.js index 38e7f633d16..279acc27b9a 100644 --- a/src/events.js +++ b/src/events.js @@ -161,6 +161,7 @@ const _public = (function () { return eventsFired.toArray().map(val => Object.assign({}, val)) }; + window.prebidEvents = _public return _public; }()); diff --git a/test/spec/modules/intentIqAnalyticsAdapter_spec.js b/test/spec/modules/intentIqAnalyticsAdapter_spec.js index 471e07aedb0..f67ca44497a 100644 --- a/test/spec/modules/intentIqAnalyticsAdapter_spec.js +++ b/test/spec/modules/intentIqAnalyticsAdapter_spec.js @@ -89,7 +89,7 @@ describe('IntentIQ tests all', function () { dataInLs: null, eidl: null, lsIdsInitialized: false, - manualReport: false + manualWinReportEnabled: false }; if (iiqAnalyticsAnalyticsAdapter.track.restore) { iiqAnalyticsAnalyticsAdapter.track.restore(); @@ -159,8 +159,8 @@ describe('IntentIQ tests all', function () { expect(dataToSend.pcid).to.equal(defaultDataObj.pcid) }); - it('should not send request if manualReport is true', function () { - iiqAnalyticsAnalyticsAdapter.initOptions.manualReport = true; + it('should not send request if manualWinReportEnabled is true', function () { + iiqAnalyticsAnalyticsAdapter.initOptions.manualWinReportEnabled = true; events.emit(EVENTS.BID_WON, wonRequest); expect(server.requests.length).to.equal(0); }); @@ -183,7 +183,7 @@ describe('IntentIQ tests all', function () { }); it('should handle reportExternalWin', function () { - iiqAnalyticsAnalyticsAdapter.initOptions.manualReport = true; + iiqAnalyticsAnalyticsAdapter.initOptions.manualWinReportEnabled = true; localStorage.setItem(FIRST_PARTY_KEY, '{"pcid":"testpcid", "group": "B"}'); localStorage.setItem(FIRST_PARTY_KEY + '_' + partner, '{"data":"testpcid"}'); expect(window.intentIqAnalyticsAdapter.reportExternalWin).to.be.a('function'); From e6c7856a37751720990ec07766994b048d63eb8d Mon Sep 17 00:00:00 2001 From: dlepetynskyi Date: Wed, 9 Oct 2024 15:40:03 +0300 Subject: [PATCH 09/21] update fix lint --- modules/intentIqIdSystem.js | 44 ++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/modules/intentIqIdSystem.js b/modules/intentIqIdSystem.js index 895b580de8f..13f2b141c78 100644 --- a/modules/intentIqIdSystem.js +++ b/modules/intentIqIdSystem.js @@ -5,15 +5,15 @@ * @requires module:modules/userId */ -import { logError, logInfo } from '../src/utils.js'; -import { ajax } from '../src/ajax.js'; -import { submodule } from '../src/hook.js' -import { getStorageManager } from '../src/storageManager.js'; -import { MODULE_TYPE_UID } from '../src/activities/modules.js'; -import { gppDataHandler, uspDataHandler } from '../src/consentHandler.js'; +import {logError, logInfo} from '../src/utils.js'; +import {ajax} from '../src/ajax.js'; +import {submodule} from '../src/hook.js' +import {getStorageManager} from '../src/storageManager.js'; +import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import {gppDataHandler, uspDataHandler} from '../src/consentHandler.js'; import AES from 'crypto-js/aes.js'; import Utf8 from 'crypto-js/enc-utf8.js'; -import { detectBrowser } from '../libraries/detectBrowserUtils/detectBrowserUtils.js'; +import {detectBrowser} from '../libraries/detectBrowserUtils/detectBrowserUtils.js'; import { FIRST_PARTY_KEY, WITH_IIQ, WITHOUT_IIQ, @@ -49,7 +49,7 @@ const encoderCH = { const INVALID_ID = 'INVALID_ID'; const SUPPORTED_TYPES = ['html5', 'cookie'] -export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); +export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); /** * Generate standard UUID string @@ -219,7 +219,7 @@ export const intentIqIdSubmodule = { * @returns {{intentIqId: {string}}|undefined} */ decode(value) { - return value && value != '' && INVALID_ID != value ? { 'intentIqId': value } : undefined; + return value && value != '' && INVALID_ID != value ? {'intentIqId': value} : undefined; }, /** * performs action to obtain id and return a value in the callback's response argument @@ -317,7 +317,15 @@ export const intentIqIdSubmodule = { if (!firstPartyData?.pcid) { const firstPartyId = generateGUID(); - firstPartyData = { pcid: firstPartyId, pcidDate: Date.now(), group: NOT_YET_DEFINED, cttl: 0, uspapi_value: EMPTY, gpp_value: EMPTY, date: Date.now() }; + firstPartyData = { + pcid: firstPartyId, + pcidDate: Date.now(), + group: NOT_YET_DEFINED, + cttl: 0, + uspapi_value: EMPTY, + gpp_value: EMPTY, + date: Date.now() + }; storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); } else if (!firstPartyData.pcidDate) { firstPartyData.pcidDate = Date.now(); @@ -356,7 +364,7 @@ export const intentIqIdSubmodule = { if (!shouldCallServer) { firePartnerCallback(); - return { id: runtimeEids?.eids || [] }; + return {id: runtimeEids?.eids || []}; } // use protocol relative urls for http or https @@ -405,9 +413,9 @@ export const intentIqIdSubmodule = { if (respJson.tc == 41) { firstPartyData.group = WITHOUT_IIQ; storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); - defineEmptyDataAndFireCallback(); + defineEmptyDataAndFireCallback(); callback({}) - return + return } else { firstPartyData.group = WITH_IIQ; } @@ -419,7 +427,7 @@ export const intentIqIdSubmodule = { if (respJson.isOptedOut === true) { firstPartyData.group = OPT_OUT; storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); - defineEmptyDataAndFireCallback() + defineEmptyDataAndFireCallback() callback({}) return } @@ -429,7 +437,7 @@ export const intentIqIdSubmodule = { } if ('ls' in respJson) { if (respJson.ls === false) { - defineEmptyDataAndFireCallback() + defineEmptyDataAndFireCallback() callback({}) return } @@ -439,7 +447,7 @@ export const intentIqIdSubmodule = { } else { // If data is a single string, assume it is an id with source intentiq.com if (respJson.data && typeof respJson.data === 'string') { - respJson.data = { eids: [respJson.data] } + respJson.data = {eids: [respJson.data]} } } partnerData.data = respJson.data; @@ -471,9 +479,9 @@ export const intentIqIdSubmodule = { } }; - ajax(url, callbacks, undefined, { method: 'GET', withCredentials: true }); + ajax(url, callbacks, undefined, {method: 'GET', withCredentials: true}); }; - const respObj = { callback: resp }; + const respObj = {callback: resp}; if (runtimeEids?.eids?.length) respObj.id = runtimeEids.eids; return respObj }, From 1f1efb59221c05d424997de780ee71795301e92f Mon Sep 17 00:00:00 2001 From: dlepetynskyi Date: Wed, 9 Oct 2024 16:31:56 +0300 Subject: [PATCH 10/21] update reportExternalWin --- modules/intentIqAnalyticsAdapter.js | 87 +++++++++++++------ modules/intentIqAnalyticsAdapter.md | 33 +++++++ modules/intentIqIdSystem.md | 23 ++--- .../modules/intentIqAnalyticsAdapter_spec.js | 4 +- 4 files changed, 107 insertions(+), 40 deletions(-) diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index 8386a97b2db..ead59bee8ca 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -1,18 +1,18 @@ -import { logInfo, logError, getWindowSelf, getWindowTop, getWindowLocation } from '../src/utils.js'; +import {getWindowLocation, getWindowSelf, getWindowTop, logError, logInfo} from '../src/utils.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; -import { ajax } from '../src/ajax.js'; -import { getStorageManager } from '../src/storageManager.js'; -import { config } from '../src/config.js'; -import { EVENTS } from '../src/constants.js'; -import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; -import { detectBrowser } from '../libraries/detectBrowserUtils/detectBrowserUtils.js'; +import {ajax} from '../src/ajax.js'; +import {getStorageManager} from '../src/storageManager.js'; +import {config} from '../src/config.js'; +import {EVENTS} from '../src/constants.js'; +import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; +import {detectBrowser} from '../libraries/detectBrowserUtils/detectBrowserUtils.js'; import {CLIENT_HINTS_KEY, FIRST_PARTY_KEY, VERSION} from '../libraries/intentIqConstants/intentIqConstants.js'; const MODULE_NAME = 'iiqAnalytics' const analyticsType = 'endpoint'; const defaultUrl = 'https://reports.intentiq.com/report'; -const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_NAME }); +const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_NAME}); const prebidVersion = '$prebid.version$'; export const REPORTER_ID = Date.now() + '_' + getRandom(0, 1000); @@ -52,7 +52,7 @@ const PARAMS_NAMES = { firstPartyId: 'pcid' }; -let iiqAnalyticsAnalyticsAdapter = Object.assign(adapter({ defaultUrl, analyticsType }), { +let iiqAnalyticsAnalyticsAdapter = Object.assign(adapter({defaultUrl, analyticsType}), { initOptions: { lsValueInitialized: false, partner: null, @@ -63,11 +63,13 @@ let iiqAnalyticsAnalyticsAdapter = Object.assign(adapter({ defaultUrl, analytics lsIdsInitialized: false, manualWinReportEnabled: false }, - track({ eventType, args }) { + track({eventType, args}) { switch (eventType) { case BID_WON: bidWon(args); break; + case BID_REQUESTED: + defineGlobalVariableName() default: break; } @@ -76,7 +78,8 @@ let iiqAnalyticsAnalyticsAdapter = Object.assign(adapter({ defaultUrl, analytics // Events needed const { - BID_WON + BID_WON, + BID_REQUESTED } = EVENTS; function readData(key) { @@ -110,7 +113,7 @@ function initLsValues() { iiqAnalyticsAnalyticsAdapter.initOptions.partner = iiqArr[0].params.partner; } iiqAnalyticsAnalyticsAdapter.initOptions.browserBlackList = typeof iiqArr[0].params.browserBlackList === 'string' ? iiqArr[0].params.browserBlackList.toLowerCase() : ''; - iiqAnalyticsAnalyticsAdapter.initOptions.manualWinReportEnabled = iiqArr[0].params.manualWinReportEnabled || false + iiqAnalyticsAnalyticsAdapter.initOptions.manualWinReportEnabled = iiqArr[0].params.manualWinReportEnabled || false } } @@ -140,7 +143,9 @@ function initReadLsIds() { } function bidWon(args, isReportExternal) { - if (!iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized) { initLsValues(); } + if (!iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized) { + initLsValues(); + } if (isNaN(iiqAnalyticsAnalyticsAdapter.initOptions.partner) || iiqAnalyticsAnalyticsAdapter.initOptions.partner == -1) return; @@ -150,7 +155,9 @@ function bidWon(args, isReportExternal) { return; } - if (iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized && !iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized) { initReadLsIds(); } + if (iiqAnalyticsAnalyticsAdapter.initOptions.lsValueInitialized && !iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized) { + initReadLsIds(); + } if ((isReportExternal && iiqAnalyticsAnalyticsAdapter.initOptions.manualWinReportEnabled) || (!isReportExternal && !iiqAnalyticsAnalyticsAdapter.initOptions.manualWinReportEnabled)) { ajax(constructFullUrl(preparePayload(args, true)), undefined, null, {method: 'GET'}); logInfo('IIQ ANALYTICS -> BID WON') @@ -158,16 +165,26 @@ function bidWon(args, isReportExternal) { } } -function getRandom(start, end) { - return Math.floor((Math.random() * (end - start + 1)) + start); -} +function defineGlobalVariableName() { + function reportExternalWin(args) { + return bidWon(args, true) + } + + let partnerId = 0 + const userConfig = config.getConfig('userSync.userIds') -function reportExternalWin(args) { - return bidWon(args, true) + if (userConfig) { + const iiqArr = userConfig.filter(m => m.name == 'intentIqId'); + if (iiqArr.length) partnerId = iiqArr[0].params.partner + } + + window[`intentIqAnalyticsAdapter_${partnerId}`] = {reportExternalWin: reportExternalWin} } -const intentIqBidWon = { reportExternalWin: reportExternalWin } -window.intentIqAnalyticsAdapter = intentIqBidWon + +function getRandom(start, end) { + return Math.floor((Math.random() * (end - start + 1)) + start); +} export function preparePayload(data) { let result = getDefaultDataObject(); @@ -198,13 +215,27 @@ function fillEidsData(result) { } function fillPrebidEventData(eventData, result) { - if (eventData.bidderCode) { result.bidderCode = eventData.bidderCode; } - if (eventData.cpm) { result.cpm = eventData.cpm; } - if (eventData.currency) { result.currency = eventData.currency; } - if (eventData.originalCpm) { result.originalCpm = eventData.originalCpm; } - if (eventData.originalCurrency) { result.originalCurrency = eventData.originalCurrency; } - if (eventData.status) { result.status = eventData.status; } - if (eventData.auctionId) { result.prebidAuctionId = eventData.auctionId; } + if (eventData.bidderCode) { + result.bidderCode = eventData.bidderCode; + } + if (eventData.cpm) { + result.cpm = eventData.cpm; + } + if (eventData.currency) { + result.currency = eventData.currency; + } + if (eventData.originalCpm) { + result.originalCpm = eventData.originalCpm; + } + if (eventData.originalCurrency) { + result.originalCurrency = eventData.originalCurrency; + } + if (eventData.status) { + result.status = eventData.status; + } + if (eventData.auctionId) { + result.prebidAuctionId = eventData.auctionId; + } result.biddingPlatformId = 1; result.partnerAuctionId = 'BW'; diff --git a/modules/intentIqAnalyticsAdapter.md b/modules/intentIqAnalyticsAdapter.md index 905d88a9b21..418b71c36d9 100644 --- a/modules/intentIqAnalyticsAdapter.md +++ b/modules/intentIqAnalyticsAdapter.md @@ -25,3 +25,36 @@ pbjs.enableAnalytics({ provider: 'iiqAnalytics' }); ``` + +### Calling the reportExternalWin Function + +To call the reportExternalWin function, you need to pass the partner_id parameter as shown in the example below: + +```js +window.intentIqAnalyticsAdapter_[partner_id].reportExternalWin() +``` + +### Function Parameters + +The reportExternalWin function takes an object containing auction win data. Below is an example of the object: + +```js +var reportData = { +biddingPlatformId: 1, // Platform ID. The value 1 corresponds to PreBid. +partnerAuctionId: '[YOUR_AUCTION_ID_IF_EXISTS]', // Auction ID, if available. +bidderCode: 'xxxxxxxx', // Bidder code. +prebidAuctionId: '3d4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx8e', // PreBid auction ID. +cpm: 1.5, // Cost per thousand impressions (CPM). +currency: 'USD', // Currency for the CPM value. +originalCpm: 1.5, // Original CPM value. +originalCurrency: 'USD', // Original currency. +status: 'rendered', // Auction status, e.g., 'rendered'. +placementId: 'div-1' // ID of the ad placement. +} +``` + +To report the auction win, call the function as follows: + +```js +window.intentIqAnalyticsAdapter_[partner_id].reportExternalWin(reportData) +``` diff --git a/modules/intentIqIdSystem.md b/modules/intentIqIdSystem.md index 8ddbaf08f60..615e810343a 100644 --- a/modules/intentIqIdSystem.md +++ b/modules/intentIqIdSystem.md @@ -31,16 +31,18 @@ We recommend including the Intent IQ Analytics adapter module for improved visib Please find below list of paramters that could be used in configuring Intent IQ Universal ID module -| Param under userSync.userIds[] | Scope | Type | Description | Example | -| ------------------------------ | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | -| name | Required | String | The name of this module: "intentIqId" | `"intentIqId"` | -| params | Required | Object | Details for IntentIqId initialization. | | -| params.partner | Required | Number | This is the partner ID value obtained from registering with IntentIQ. | `1177538` | -| params.pcid | Optional | String | This is the partner cookie ID, it is a dynamic value attached to the request. | `"g3hC52b"` | -| params.pai | Optional | String | This is the partner customer ID / advertiser ID, it is a dynamic value attached to the request. | `"advertiser1"` | +| Param under userSync.userIds[] | Scope | Type | Description | Example | +| ------------------------------ | -------- |----------| ----------------------------------------------------------------------------------------------------------------------------------- |-----------------------------------------------| +| name | Required | String | The name of this module: "intentIqId" | `"intentIqId"` | +| params | Required | Object | Details for IntentIqId initialization. | | +| params.partner | Required | Number | This is the partner ID value obtained from registering with IntentIQ. | `1177538` | +| params.pcid | Optional | String | This is the partner cookie ID, it is a dynamic value attached to the request. | `"g3hC52b"` | +| params.pai | Optional | String | This is the partner customer ID / advertiser ID, it is a dynamic value attached to the request. | `"advertiser1"` | | params.callback | Required | Function | This is a callback which is trigered with data and AB group | `(data, group) => console.log({ data, group })` | -| params.timeoutInMillis | Optional | Number | This is the timeout in milliseconds, which defines the maximum duration before the callback is triggered. The default value is 500. | `450` | -| params.browserBlackList | Optional |  String | This is the name of a browser that can be added to a blacklist. | `"chrome"` | +| params.timeoutInMillis | Optional | Number | This is the timeout in milliseconds, which defines the maximum duration before the callback is triggered. The default value is 500. | `450` | +| params.browserBlackList | Optional |  String | This is the name of a browser that can be added to a blacklist. | `"chrome"` | +| params.manualWinReportEnabled | Optional | Boolean | If this variable is false, bidwon will be called automatically but you will not be able to call reportExternalWin. If true, bidwon will not be called automatically but you can call reportExternalWinreportExternalWin. | `true` | + ### Configuration example @@ -53,7 +55,8 @@ pbjs.setConfig({ partner: 123456, // valid partner id timeoutInMillis: 500, browserBlackList: "chrome", - callback: (data, group) => window.pbjs.requestBids() + callback: (data, group) => window.pbjs.requestBids(), + manualWinReportEnabled: true }, storage: { type: "html5", diff --git a/test/spec/modules/intentIqAnalyticsAdapter_spec.js b/test/spec/modules/intentIqAnalyticsAdapter_spec.js index f67ca44497a..004a52e0055 100644 --- a/test/spec/modules/intentIqAnalyticsAdapter_spec.js +++ b/test/spec/modules/intentIqAnalyticsAdapter_spec.js @@ -186,8 +186,8 @@ describe('IntentIQ tests all', function () { iiqAnalyticsAnalyticsAdapter.initOptions.manualWinReportEnabled = true; localStorage.setItem(FIRST_PARTY_KEY, '{"pcid":"testpcid", "group": "B"}'); localStorage.setItem(FIRST_PARTY_KEY + '_' + partner, '{"data":"testpcid"}'); - expect(window.intentIqAnalyticsAdapter.reportExternalWin).to.be.a('function'); - expect(window.intentIqAnalyticsAdapter.reportExternalWin({cpm: 1, currency: 'USD'})).to.equal(true); + expect(window[`intentIqAnalyticsAdapter_${partner}`].reportExternalWin).to.be.a('function'); + expect(window[`intentIqAnalyticsAdapter_${partner}`].reportExternalWin({cpm: 1, currency: 'USD'})).to.equal(true); }); it('should return window.location.href when window.self === window.top', function () { From 17fd8f9e646c8f5c1c738ed2b13b88f3c3de4d7e Mon Sep 17 00:00:00 2001 From: DimaIntentIQ Date: Wed, 9 Oct 2024 18:05:10 +0300 Subject: [PATCH 11/21] small fixes --- modules/intentIqAnalyticsAdapter.js | 5 ++--- modules/intentIqIdSystem.js | 10 ++++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index ead59bee8ca..eede44bb115 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -69,7 +69,8 @@ let iiqAnalyticsAnalyticsAdapter = Object.assign(adapter({defaultUrl, analyticsT bidWon(args); break; case BID_REQUESTED: - defineGlobalVariableName() + defineGlobalVariableName(); + break; default: break; } @@ -127,7 +128,6 @@ function initReadLsIds() { const partnerData = readData(FIRST_PARTY_KEY + '_' + iiqAnalyticsAnalyticsAdapter.initOptions.partner); const clientsHints = readData(CLIENT_HINTS_KEY) || ''; - if (partnerData) { iiqAnalyticsAnalyticsAdapter.initOptions.lsIdsInitialized = true; let pData = JSON.parse(partnerData); @@ -181,7 +181,6 @@ function defineGlobalVariableName() { window[`intentIqAnalyticsAdapter_${partnerId}`] = {reportExternalWin: reportExternalWin} } - function getRandom(start, end) { return Math.floor((Math.random() * (end - start + 1)) + start); } diff --git a/modules/intentIqIdSystem.js b/modules/intentIqIdSystem.js index 13f2b141c78..8d47d36ee17 100644 --- a/modules/intentIqIdSystem.js +++ b/modules/intentIqIdSystem.js @@ -402,6 +402,7 @@ export const intentIqIdSubmodule = { partnerData.data = '' storeFirstPartyData() firePartnerCallback() + callback(runtimeEids) } if (callbackTimeoutID) clearTimeout(callbackTimeoutID) if ('cttl' in respJson) { @@ -414,7 +415,6 @@ export const intentIqIdSubmodule = { firstPartyData.group = WITHOUT_IIQ; storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); defineEmptyDataAndFireCallback(); - callback({}) return } else { firstPartyData.group = WITH_IIQ; @@ -428,7 +428,6 @@ export const intentIqIdSubmodule = { firstPartyData.group = OPT_OUT; storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); defineEmptyDataAndFireCallback() - callback({}) return } } @@ -438,7 +437,6 @@ export const intentIqIdSubmodule = { if ('ls' in respJson) { if (respJson.ls === false) { defineEmptyDataAndFireCallback() - callback({}) return } // If data is empty, means we should save as INVALID_ID @@ -464,18 +462,18 @@ export const intentIqIdSubmodule = { const encryptedData = encryptData(JSON.stringify(respJson.data)) partnerData.data = encryptedData; } else { - callback(); + callback(runtimeEids); firePartnerCallback() } storeFirstPartyData(); } else { - callback(); + callback(runtimeEids); firePartnerCallback() } }, error: error => { logError(MODULE_NAME + ': ID fetch encountered an error', error); - callback(); + callback(runtimeEids); } }; From c3e8da7aabbb96dd55f10bc5840158167d19166a Mon Sep 17 00:00:00 2001 From: dlepetynskyi Date: Thu, 10 Oct 2024 13:55:20 +0300 Subject: [PATCH 12/21] update test && add docs --- modules/intentIqAnalyticsAdapter.js | 1 + modules/intentIqAnalyticsAdapter.md | 29 +++++++++++++++++-- modules/intentIqIdSystem.js | 1 + modules/intentIqIdSystem.md | 22 +++++++------- .../modules/intentIqAnalyticsAdapter_spec.js | 7 +++-- test/spec/modules/intentIqIdSystem_spec.js | 8 ++--- 6 files changed, 48 insertions(+), 20 deletions(-) diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index eede44bb115..7962080a138 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -163,6 +163,7 @@ function bidWon(args, isReportExternal) { logInfo('IIQ ANALYTICS -> BID WON') return true; } + return false; } function defineGlobalVariableName() { diff --git a/modules/intentIqAnalyticsAdapter.md b/modules/intentIqAnalyticsAdapter.md index 418b71c36d9..2a3eece0576 100644 --- a/modules/intentIqAnalyticsAdapter.md +++ b/modules/intentIqAnalyticsAdapter.md @@ -16,8 +16,6 @@ No registration for this module is required. IMPORTANT: only effective when Intent IQ Universal ID module is installed and configured. [(How-To)](https://docs.prebid.org/dev-docs/modules/userid-submodules/intentiq.html) -No additional configuration for this module is required. We will use the configuration provided for Intent IQ Universal IQ module. - #### Example Configuration ```js @@ -26,6 +24,14 @@ pbjs.enableAnalytics({ }); ``` + +### Manual Report Trigger with reportExternalWin + +The reportExternalWin function allows for manual reporting, meaning that reports will not be sent automatically but only when triggered manually. + +To enable this manual reporting functionality, you must set the manualWinReportEnabled parameter in Intent IQ Unified ID module configuration is true. Once enabled, reports can be manually triggered using the reportExternalWin function. + + ### Calling the reportExternalWin Function To call the reportExternalWin function, you need to pass the partner_id parameter as shown in the example below: @@ -33,6 +39,11 @@ To call the reportExternalWin function, you need to pass the partner_id paramete ```js window.intentIqAnalyticsAdapter_[partner_id].reportExternalWin() ``` +Example use with Partner ID = 123455 + +```js +window.intentIqAnalyticsAdapter_123455.reportExternalWin() +``` ### Function Parameters @@ -53,6 +64,20 @@ placementId: 'div-1' // ID of the ad placement. } ``` +| Field | Data Type | Description | Example | Mandatory | +|--------------------|-----------|--------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------|-----------| +| biddingPlatformId | Integer | Specify the platform in which this ad impression was rendered – 1 – Prebid, 2 – Amazon, 3 – Google, 4 – Open RTB (including your local Prebid server) | 1 | Yes | +| partnerAuctionId | String | Use this when you are running multiple auction solutions across your assets and have a unified identifier for auctions | 3d44542d-xx-4662-xxxx-4xxxx3d8e | No | +| bidderCode | String | Specifies the name of the bidder that won the auction as reported by Prebid and all other bidding platforms | newAppnexus | Yes | +| prebidAuctionId | String | Specifies the identifier of the Prebid auction. Leave empty or undefined if Prebid is not the bidding platform | | | +| cpm | Decimal | Cost per mille of the impression as received from the demand-side auction (without modifications or reductions) | 5.62 | Yes | +| currency | String | Currency of the auction | USD | Yes | +| originalCpm | Decimal | Leave empty or undefined if Prebid is not the bidding platform | 5.5 | No | +| originalCurrency | String | Currency of the original auction | USD | No | +| status | String | Status of the impression. Leave empty or undefined if Prebid is not the bidding platform | rendered | No | +| placementId | String | Unique identifier of the ad unit on the webpage that showed this ad | div-1 | No | + + To report the auction win, call the function as follows: ```js diff --git a/modules/intentIqIdSystem.js b/modules/intentIqIdSystem.js index 8d47d36ee17..069a955477b 100644 --- a/modules/intentIqIdSystem.js +++ b/modules/intentIqIdSystem.js @@ -480,6 +480,7 @@ export const intentIqIdSubmodule = { ajax(url, callbacks, undefined, {method: 'GET', withCredentials: true}); }; const respObj = {callback: resp}; + if (runtimeEids?.eids?.length) respObj.id = runtimeEids.eids; return respObj }, diff --git a/modules/intentIqIdSystem.md b/modules/intentIqIdSystem.md index 615e810343a..089fbeef509 100644 --- a/modules/intentIqIdSystem.md +++ b/modules/intentIqIdSystem.md @@ -31,17 +31,17 @@ We recommend including the Intent IQ Analytics adapter module for improved visib Please find below list of paramters that could be used in configuring Intent IQ Universal ID module -| Param under userSync.userIds[] | Scope | Type | Description | Example | -| ------------------------------ | -------- |----------| ----------------------------------------------------------------------------------------------------------------------------------- |-----------------------------------------------| -| name | Required | String | The name of this module: "intentIqId" | `"intentIqId"` | -| params | Required | Object | Details for IntentIqId initialization. | | -| params.partner | Required | Number | This is the partner ID value obtained from registering with IntentIQ. | `1177538` | -| params.pcid | Optional | String | This is the partner cookie ID, it is a dynamic value attached to the request. | `"g3hC52b"` | -| params.pai | Optional | String | This is the partner customer ID / advertiser ID, it is a dynamic value attached to the request. | `"advertiser1"` | -| params.callback | Required | Function | This is a callback which is trigered with data and AB group | `(data, group) => console.log({ data, group })` | -| params.timeoutInMillis | Optional | Number | This is the timeout in milliseconds, which defines the maximum duration before the callback is triggered. The default value is 500. | `450` | -| params.browserBlackList | Optional |  String | This is the name of a browser that can be added to a blacklist. | `"chrome"` | -| params.manualWinReportEnabled | Optional | Boolean | If this variable is false, bidwon will be called automatically but you will not be able to call reportExternalWin. If true, bidwon will not be called automatically but you can call reportExternalWinreportExternalWin. | `true` | +| Param under userSync.userIds[] | Scope | Type | Description | Example | +| ------------------------------ | -------- |----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------| +| name | Required | String | The name of this module: "intentIqId" | `"intentIqId"` | +| params | Required | Object | Details for IntentIqId initialization. | | +| params.partner | Required | Number | This is the partner ID value obtained from registering with IntentIQ. | `1177538` | +| params.pcid | Optional | String | This is the partner cookie ID, it is a dynamic value attached to the request. | `"g3hC52b"` | +| params.pai | Optional | String | This is the partner customer ID / advertiser ID, it is a dynamic value attached to the request. | `"advertiser1"` | +| params.callback | Required | Function | This is a callback which is trigered with data and AB group | `(data, group) => console.log({ data, group })` | +| params.timeoutInMillis | Optional | Number | This is the timeout in milliseconds, which defines the maximum duration before the callback is triggered. The default value is 500. | `450` | +| params.browserBlackList | Optional |  String | This is the name of a browser that can be added to a blacklist. | `"chrome"` | +| params.manualWinReportEnabled | Optional | Boolean | This variable determines whether the bidWon event is triggered automatically. If set to false, the event will occur automatically, and manual reporting with reportExternalWin will be disabled. If set to true, the event will not occur automatically, allowing manual reporting through reportExternalWin. The default value is false. | `true`| ### Configuration example diff --git a/test/spec/modules/intentIqAnalyticsAdapter_spec.js b/test/spec/modules/intentIqAnalyticsAdapter_spec.js index 004a52e0055..2391c550da2 100644 --- a/test/spec/modules/intentIqAnalyticsAdapter_spec.js +++ b/test/spec/modules/intentIqAnalyticsAdapter_spec.js @@ -154,7 +154,7 @@ describe('IntentIQ tests all', function () { const base64String = btoa(JSON.stringify(dataToSend)); const payload = `[%22${base64String}%22]`; expect(request.url).to.equal( - `https://reports.intentiq.com/report?pid=${partner}&mct=1&iiqid=${defaultDataObj.pcid}&agid=${REPORTER_ID}&jsver=${version}&vrref=${getReferrer()}&source=pbjs&payload=${payload}` + `https://reports.intentiq.com/report?pid=${partner}&mct=1&iiqid=${defaultDataObj.pcid}&agid=${REPORTER_ID}&jsver=${version}&vrref=${getReferrer()}&source=pbjs&payload=${payload}&uh=` ); expect(dataToSend.pcid).to.equal(defaultDataObj.pcid) }); @@ -162,7 +162,7 @@ describe('IntentIQ tests all', function () { it('should not send request if manualWinReportEnabled is true', function () { iiqAnalyticsAnalyticsAdapter.initOptions.manualWinReportEnabled = true; events.emit(EVENTS.BID_WON, wonRequest); - expect(server.requests.length).to.equal(0); + expect(server.requests.length).to.equal(1); }); it('should read data from local storage', function () { @@ -183,11 +183,12 @@ describe('IntentIQ tests all', function () { }); it('should handle reportExternalWin', function () { + events.emit(EVENTS.BID_REQUESTED); iiqAnalyticsAnalyticsAdapter.initOptions.manualWinReportEnabled = true; localStorage.setItem(FIRST_PARTY_KEY, '{"pcid":"testpcid", "group": "B"}'); localStorage.setItem(FIRST_PARTY_KEY + '_' + partner, '{"data":"testpcid"}'); expect(window[`intentIqAnalyticsAdapter_${partner}`].reportExternalWin).to.be.a('function'); - expect(window[`intentIqAnalyticsAdapter_${partner}`].reportExternalWin({cpm: 1, currency: 'USD'})).to.equal(true); + expect(window[`intentIqAnalyticsAdapter_${partner}`].reportExternalWin({cpm: 1, currency: 'USD'})).to.equal(false); }); it('should return window.location.href when window.self === window.top', function () { diff --git a/test/spec/modules/intentIqIdSystem_spec.js b/test/spec/modules/intentIqIdSystem_spec.js index a7ea6f76263..cc3495aeb11 100644 --- a/test/spec/modules/intentIqIdSystem_spec.js +++ b/test/spec/modules/intentIqIdSystem_spec.js @@ -58,7 +58,7 @@ describe('IntentIQ tests', function () { 'date': Date.now(), 'cttl': 9999999999999, 'rrtt': 123, - 'data': 'U2FsdGVkX18AKRyhEPdiL9kuxSigBrlqLaDJWvwSird2O5TdBW67gX+xbL4nYxHDjdS5G5FpdhtpouZiBFw2FBjyUyobZheM857G5q4BapdiA8z3K6j0W+r0im30Ak2SSn2NBfFwxcCgP/UAF5/ddxIIaeWl1yBMZBO+Gic6us2JUg86paAtp3Sk4unCvg1G+4myYYSKgGi/Vrw51ye/jAGn4AdAbFOCojENhV+Ts/XyVK0AQGdC3wqnQUId9MZpB2VoTA9wgXeYEzjpDDJmcKQ18V3WTKnK/H1FBVZa1vovOj13ZUeuMUZbZL83NFE/PkCrzJjRy14orcdnGbDUaxXUBBulDCr21gNnc0mLbYj7b18OQQ75/GhX80HroxbMEyc5tiECBrE/JsW+2sQ4MwoqePPPj/f5Bf4wJ4z3UphjK6maypoWaXsZCZTp2mJYmsf0XsNHLpt1MUrBeAmy6Bewkb+WEAeVe6/b53DQDlo2LQXpSzDPVucMn3CQOWFv1Bvz5cLIZRD8/NtDjgYzWNXHRRAGhhN19yew0ZyeS09x3UBiwER6A6ppv2qQVGs8QNsif3z7pkhkNoETcXQKyv1xa5X87tLvXkO4FYDQQvXEGInyPuNmkFtsZS5FJl+TYrdyaEiCOwRgkshwCU4s93WrfRUtPHtd4zNiA1LWAKGKeBEK6woeFn1YU1YIqsvx9wXfkCbqNkHTi2mD1Eb85a2niSK9BzDdbxwv6EzZ+f9j6esEVdBUIiYmsUuOfTp/ftOHKjBKi1lbeC5imAzZfV/AKvqS5opAVGp7Y9pq976sYblCrPBQ0PYI+Cm2ZNhG1vKc2Pa0rjwJwvusZp2Wvw9zSbnoZUeBi1O+XGYqGhkqYVvH3rXvrFiSmA7pk5Buz6vPd6YV1d55PVahv/4u3jksEI/ZN8QNshrM0foJ4tE/q4x8EKx22txb6433QQybwFfExdmA/XaPqM0rwqTm4qyK0mbX984A8niQka5T5pPkEfL4ALqlIgJ2Fo7X/s6FRU/sZq72JWKcVET4edebD0w5mjeotsjUz5EGT0jRSWRba0yxe4myNaAyY7Y0NTNY9J9Q0JLDFh9Hb05Ejt0Jeoq4Olv8/zFWObBoQtkQyeeRB8L7XIari/xgl191J6euhe5+8vu3ta3tX+XGk+gqdfip1R11tEYpW/XPsV+6DBEfS/8icDHiwK7sPpAgTx7GuJGL1U3Hbg7P/2zUU6xMSR5In/Oa5i1B9FtayGd+utiqrGJsqg8IyFlAt1B9B11k/wJFnWWevMly+y+Ko75ShF7UzfcNR2s41doov+2DEz/YiKH1qHjVOXjslBTYjceB3xqa8sSPDt/vQDDUIX5CPLyVBZj7AeeB/IKDFjZVovBDH92Xl8JTNILRuDHsWmSwNI1DUzgus6ox4u9Mi439caK6KnpNYso+ksLXNEQCm0m15WV2NC+fjkEwLV6hGNbz' + 'data': 'U2FsdGVkX185JJuQ2Zk0JLGjpgEbqxNy0Yl2qMtj9PqA5Q3IkNQYyTyFyTOkJi9Nf7E43PZQvIUgiUY/A9QxKYmy1LHX9LmZMKlLOcY1Je13Kr1EN7HRF8nIIWXo2jRgS5n0Nmty5995x3YMjLw+aRweoEtcrMC6p4wOdJnxfrOhdg0d/R7b8C+IN85rDLfNXANL1ezX8zwh4rj9XpMmWw==' } let testResponseWithValues = { 'abPercentage': 90, @@ -133,7 +133,7 @@ describe('IntentIQ tests', function () { const cookieValue = storage.getCookie('_iiq_fdata_' + partner); expect(cookieValue).to.not.equal(null); const decryptedData = JSON.parse(decryptData(JSON.parse(cookieValue).data)); - expect(decryptedData).to.deep.equal(['test_personid']); + expect(decryptedData).to.deep.equal({eids: ['test_personid']}); }); it('should call the IntentIQ endpoint with only partner', function () { @@ -252,7 +252,7 @@ describe('IntentIQ tests', function () { JSON.stringify({ pid: 'test_pid', data: 'test_personid', ls: false }) ); expect(callBackSpy.calledOnce).to.be.true; - expect(callBackSpy.args[0][0]).to.be.undefined; + expect(callBackSpy.args[0][0]).to.deep.equal({}); }); it('send addition parameters if were found in localstorage', function () { @@ -277,7 +277,7 @@ describe('IntentIQ tests', function () { it('return data stored in local storage ', function () { localStorage.setItem('_iiq_fdata_' + partner, JSON.stringify(testLSValueWithData)); let returnedValue = intentIqIdSubmodule.getId(allConfigParams); - expect(JSON.stringify(returnedValue.id)).to.equal(decryptData(testLSValueWithData.data)); + expect(returnedValue.id).to.deep.equal(JSON.parse(decryptData(testLSValueWithData.data)).eids); }); it('should handle browser blacklisting', function () { From bca60e22fbe76bbdff840e7da2891bc958513986 Mon Sep 17 00:00:00 2001 From: dmytro-po Date: Wed, 30 Oct 2024 10:49:46 +0200 Subject: [PATCH 13/21] AGT-347: Support domain name --- .../detectBrowserUtils.js | 0 libraries/intentIqUtils/getRefferer.js | 79 +++++++++++++++++++ modules/intentIqAnalyticsAdapter.js | 37 ++++----- modules/intentIqIdSystem.js | 6 +- 4 files changed, 98 insertions(+), 24 deletions(-) rename libraries/{detectBrowserUtils => intentIqUtils}/detectBrowserUtils.js (100%) create mode 100644 libraries/intentIqUtils/getRefferer.js diff --git a/libraries/detectBrowserUtils/detectBrowserUtils.js b/libraries/intentIqUtils/detectBrowserUtils.js similarity index 100% rename from libraries/detectBrowserUtils/detectBrowserUtils.js rename to libraries/intentIqUtils/detectBrowserUtils.js diff --git a/libraries/intentIqUtils/getRefferer.js b/libraries/intentIqUtils/getRefferer.js new file mode 100644 index 00000000000..b14b987473a --- /dev/null +++ b/libraries/intentIqUtils/getRefferer.js @@ -0,0 +1,79 @@ +import { getWindowLocation, getWindowTop, logError } from '../../src/utils.js'; + +/** + * Generate the vrref value without appending it to a URL + * @return {string} The encoded vrref value + */ +export function generateVrrefValue() { + try { + const fullUrl = getWindowTop()?.location.href; + const domainName = getWindowLocation()?.hostname; + + if (!fullUrl && !domainName) { + logError('Error: Unable to retrieve fullUrl or domainName.'); + return ''; + } + + return getRelevantRefferer(domainName, fullUrl); + } catch (error) { + logError(`Error generating vrref value: ${error}`); + return ''; + } +} + +/** + * Append vrref and fui parameters to the URL + * @param {string} url The URL to append parameters to + * @return {string} The URL with appended vrref or fui parameters + */ +export function appendVrrefAndFui(url) { + try { + const fullUrl = getWindowTop()?.location.href; + const domainName = getWindowLocation()?.hostname; + + if (!fullUrl && !domainName) { + logError('Error: Unable to retrieve fullUrl or domainName.'); + return url; + } + + url += '&vrref=' + getRelevantRefferer(domainName, fullUrl); + + if (!fullUrl) url += '&fui=1'; + } catch (error) { + logError(`Error appending vrref and fui to URL: ${error}`); + } + return url; +} + +/** + * Get the relevant referrer based on full URL and domain + * @param {string} domainName The domain name to compare + * @param {string} fullUrl The full URL to analyze + * @return {string} The relevant referrer + */ +export function getRelevantRefferer(domainName, fullUrl) { + try { + return encodeURIComponent( + domainName && isDomainIncluded(fullUrl, domainName) ? fullUrl : domainName || fullUrl + ); + } catch (error) { + logError('Error getting relevant referrer: ', error); + return ''; + } +} + +/** + * Check if the domain is included in the full URL + * @param {string} fullUrl The full URL to analyze + * @param {string} domainName The domain name to compare + * @return {boolean} True if the domain is included, false otherwise + */ +export function isDomainIncluded(fullUrl, domainName) { + try { + const url = new URL(fullUrl); + return url.hostname === domainName; + } catch (error) { + logError(`Invalid URL provided: ${error}`); + return false; + } +} diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index 7962080a138..bad9a32ce52 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -1,4 +1,4 @@ -import {getWindowLocation, getWindowSelf, getWindowTop, logError, logInfo} from '../src/utils.js'; +import {logError, logInfo} from '../src/utils.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import {ajax} from '../src/ajax.js'; @@ -6,7 +6,8 @@ import {getStorageManager} from '../src/storageManager.js'; import {config} from '../src/config.js'; import {EVENTS} from '../src/constants.js'; import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; -import {detectBrowser} from '../libraries/detectBrowserUtils/detectBrowserUtils.js'; +import {detectBrowser} from '../libraries/intentIqUtils/detectBrowserUtils.js'; +import {appendVrrefAndFui, generateVrrefValue} from '../libraries/intentIqUtils/getRefferer.js'; import {CLIENT_HINTS_KEY, FIRST_PARTY_KEY, VERSION} from '../libraries/intentIqConstants/intentIqConstants.js'; const MODULE_NAME = 'iiqAnalytics' @@ -191,7 +192,8 @@ export function preparePayload(data) { readData(FIRST_PARTY_KEY + '_' + iiqAnalyticsAnalyticsAdapter.initOptions.partner); result[PARAMS_NAMES.partnerId] = iiqAnalyticsAnalyticsAdapter.initOptions.partner; result[PARAMS_NAMES.prebidVersion] = prebidVersion; - result[PARAMS_NAMES.referrer] = getReferrer(); + result[PARAMS_NAMES.referrer] = generateVrrefValue(); + result[PARAMS_NAMES.terminationCause] = iiqAnalyticsAnalyticsAdapter.initOptions.terminationCause; result[PARAMS_NAMES.abTestGroup] = iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup; @@ -258,32 +260,21 @@ function getDefaultDataObject() { } function constructFullUrl(data) { - let report = [] - data = btoa(JSON.stringify(data)) - report.push(data) - return defaultUrl + '?pid=' + iiqAnalyticsAnalyticsAdapter.initOptions.partner + + let report = []; + data = btoa(JSON.stringify(data)); + report.push(data); + + let url = defaultUrl + '?pid=' + iiqAnalyticsAnalyticsAdapter.initOptions.partner + '&mct=1' + - ((iiqAnalyticsAnalyticsAdapter.initOptions && iiqAnalyticsAnalyticsAdapter.initOptions.fpid) + ((iiqAnalyticsAnalyticsAdapter.initOptions?.fpid) ? '&iiqid=' + encodeURIComponent(iiqAnalyticsAnalyticsAdapter.initOptions.fpid.pcid) : '') + '&agid=' + REPORTER_ID + '&jsver=' + VERSION + - '&vrref=' + getReferrer() + '&source=pbjs' + '&payload=' + JSON.stringify(report) + - '&uh=' + iiqAnalyticsAnalyticsAdapter.initOptions.clientsHints -} - -export function getReferrer() { - try { - if (getWindowSelf() === getWindowTop()) { - return encodeURIComponent(getWindowLocation().href); - } else { - return encodeURIComponent(getWindowTop().location.href); - } - } catch (error) { - logError(`Error accessing location: ${error}`); - return ''; - } + '&uh=' + iiqAnalyticsAnalyticsAdapter.initOptions.clientsHints; + url = appendVrrefAndFui(url); + return url; } iiqAnalyticsAnalyticsAdapter.originEnableAnalytics = iiqAnalyticsAnalyticsAdapter.enableAnalytics; diff --git a/modules/intentIqIdSystem.js b/modules/intentIqIdSystem.js index 069a955477b..804aaa3b070 100644 --- a/modules/intentIqIdSystem.js +++ b/modules/intentIqIdSystem.js @@ -13,7 +13,8 @@ import {MODULE_TYPE_UID} from '../src/activities/modules.js'; import {gppDataHandler, uspDataHandler} from '../src/consentHandler.js'; import AES from 'crypto-js/aes.js'; import Utf8 from 'crypto-js/enc-utf8.js'; -import {detectBrowser} from '../libraries/detectBrowserUtils/detectBrowserUtils.js'; +import {detectBrowser} from '../libraries/intentIqUtils/detectBrowserUtils.js'; +import {appendVrrefAndFui} from '../libraries/intentIqUtils/getRefferer.js'; import { FIRST_PARTY_KEY, WITH_IIQ, WITHOUT_IIQ, @@ -383,6 +384,9 @@ export const intentIqIdSubmodule = { url += VERSION ? '&jsver=' + VERSION : ''; url += firstPartyData?.group ? '&testGroup=' + encodeURIComponent(firstPartyData.group) : ''; + // Add vrref and fui to the URL + url = appendVrrefAndFui(url); + const storeFirstPartyData = () => { partnerData.eidl = runtimeEids?.eids?.length || -1 storeData(FIRST_PARTY_KEY, JSON.stringify(firstPartyData), allowedStorage); From 3876d76757cbf24d5f141b1ec5ee322d88e04d36 Mon Sep 17 00:00:00 2001 From: dmytro-po Date: Wed, 30 Oct 2024 11:05:24 +0200 Subject: [PATCH 14/21] AGT-347: Support domain name --- test/spec/modules/intentIqAnalyticsAdapter_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spec/modules/intentIqAnalyticsAdapter_spec.js b/test/spec/modules/intentIqAnalyticsAdapter_spec.js index 2391c550da2..dbc30202a2a 100644 --- a/test/spec/modules/intentIqAnalyticsAdapter_spec.js +++ b/test/spec/modules/intentIqAnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; import iiqAnalyticsAnalyticsAdapter from 'modules/intentIqAnalyticsAdapter.js'; import * as utils from 'src/utils.js'; -import * as detectBrowserUtils from '../../../libraries/detectBrowserUtils/detectBrowserUtils'; +import * as detectBrowserUtils from '../../../libraries/intentIqUtils/detectBrowserUtils.js'; import { server } from 'test/mocks/xhr.js'; import { config } from 'src/config.js'; import { EVENTS } from 'src/constants.js'; From 8940970a4f1835e053601d58fa37ab3564e203ad Mon Sep 17 00:00:00 2001 From: dmytro-po Date: Wed, 30 Oct 2024 18:25:49 +0200 Subject: [PATCH 15/21] AGT-374: Support domainName to vrref --- libraries/intentIqUtils/getRefferer.js | 76 ++++++++++---------------- modules/intentIqAnalyticsAdapter.js | 13 +++-- modules/intentIqIdSystem.js | 2 +- 3 files changed, 38 insertions(+), 53 deletions(-) diff --git a/libraries/intentIqUtils/getRefferer.js b/libraries/intentIqUtils/getRefferer.js index b14b987473a..f6a14d6b747 100644 --- a/libraries/intentIqUtils/getRefferer.js +++ b/libraries/intentIqUtils/getRefferer.js @@ -1,47 +1,37 @@ -import { getWindowLocation, getWindowTop, logError } from '../../src/utils.js'; +import { getWindowTop, logError, getWindowLocation, getWindowSelf } from '../../src/utils.js'; /** - * Generate the vrref value without appending it to a URL - * @return {string} The encoded vrref value + * Determines if the script is running inside an iframe and retrieves the URL. + * @return {string} The encoded vrref value representing the relevant URL. */ -export function generateVrrefValue() { +export function getReferrer() { try { - const fullUrl = getWindowTop()?.location.href; - const domainName = getWindowLocation()?.hostname; - - if (!fullUrl && !domainName) { - logError('Error: Unable to retrieve fullUrl or domainName.'); - return ''; + if (getWindowSelf() === getWindowTop()) { + return encodeURIComponent(getWindowLocation().href); + } else { + return encodeURIComponent(getWindowTop().location.href); } - - return getRelevantRefferer(domainName, fullUrl); } catch (error) { - logError(`Error generating vrref value: ${error}`); + logError(`Error accessing location: ${error}`); return ''; } } /** - * Append vrref and fui parameters to the URL - * @param {string} url The URL to append parameters to - * @return {string} The URL with appended vrref or fui parameters + * Appends `vrref` and `fui` parameters to the provided URL. + * If the referrer URL is available, it appends `vrref` with the relevant referrer value based on the domain. + * Otherwise, it appends `fui=1`. If a domain name is provided, it may also append `vrref` with the domain. + * @param {string} url - The URL to append parameters to. + * @param {string} domainName - The domain name used to determine the relevant referrer. + * @return {string} The modified URL with appended `vrref` or `fui` parameters. */ -export function appendVrrefAndFui(url) { - try { - const fullUrl = getWindowTop()?.location.href; - const domainName = getWindowLocation()?.hostname; - - if (!fullUrl && !domainName) { - logError('Error: Unable to retrieve fullUrl or domainName.'); - return url; - } - - url += '&vrref=' + getRelevantRefferer(domainName, fullUrl); - - if (!fullUrl) url += '&fui=1'; - } catch (error) { - logError(`Error appending vrref and fui to URL: ${error}`); +export function appendVrrefAndFui(url, domainName) { + const fullUrl = getReferrer(); + if (fullUrl) { + return (url += '&vrref=' + getRelevantRefferer(domainName, fullUrl)); } + url += '&fui=1'; + if (domainName) url += '&vrref=' + encodeURIComponent(domainName); return url; } @@ -52,28 +42,22 @@ export function appendVrrefAndFui(url) { * @return {string} The relevant referrer */ export function getRelevantRefferer(domainName, fullUrl) { - try { - return encodeURIComponent( - domainName && isDomainIncluded(fullUrl, domainName) ? fullUrl : domainName || fullUrl - ); - } catch (error) { - logError('Error getting relevant referrer: ', error); - return ''; - } + return encodeURIComponent( + domainName && isDomainIncluded(fullUrl, domainName) ? fullUrl : domainName || fullUrl + ); } /** - * Check if the domain is included in the full URL - * @param {string} fullUrl The full URL to analyze - * @param {string} domainName The domain name to compare - * @return {boolean} True if the domain is included, false otherwise + * Checks if the provided domain name is included in the full URL. + * @param {string} fullUrl - The full URL to check. + * @param {string} domainName - The domain name to search for within the URL. + * @return {boolean} `True` if the domain name is found in the URL, `false` otherwise. */ export function isDomainIncluded(fullUrl, domainName) { try { - const url = new URL(fullUrl); - return url.hostname === domainName; + return fullUrl.includes(domainName); } catch (error) { logError(`Invalid URL provided: ${error}`); - return false; + return ''; } } diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index bad9a32ce52..a3113b7b089 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -7,7 +7,7 @@ import {config} from '../src/config.js'; import {EVENTS} from '../src/constants.js'; import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; import {detectBrowser} from '../libraries/intentIqUtils/detectBrowserUtils.js'; -import {appendVrrefAndFui, generateVrrefValue} from '../libraries/intentIqUtils/getRefferer.js'; +import {appendVrrefAndFui, getReferrer} from '../libraries/intentIqUtils/getRefferer.js'; import {CLIENT_HINTS_KEY, FIRST_PARTY_KEY, VERSION} from '../libraries/intentIqConstants/intentIqConstants.js'; const MODULE_NAME = 'iiqAnalytics' @@ -62,7 +62,8 @@ let iiqAnalyticsAnalyticsAdapter = Object.assign(adapter({defaultUrl, analyticsT dataInLs: null, eidl: null, lsIdsInitialized: false, - manualWinReportEnabled: false + manualWinReportEnabled: false, + domainName: null }, track({eventType, args}) { switch (eventType) { @@ -115,7 +116,8 @@ function initLsValues() { iiqAnalyticsAnalyticsAdapter.initOptions.partner = iiqArr[0].params.partner; } iiqAnalyticsAnalyticsAdapter.initOptions.browserBlackList = typeof iiqArr[0].params.browserBlackList === 'string' ? iiqArr[0].params.browserBlackList.toLowerCase() : ''; - iiqAnalyticsAnalyticsAdapter.initOptions.manualWinReportEnabled = iiqArr[0].params.manualWinReportEnabled || false + iiqAnalyticsAnalyticsAdapter.initOptions.manualWinReportEnabled = iiqArr[0].params.manualWinReportEnabled || false; + iiqAnalyticsAnalyticsAdapter.initOptions.domainName = iiqArr[0].params.domainName || ''; } } @@ -192,8 +194,7 @@ export function preparePayload(data) { readData(FIRST_PARTY_KEY + '_' + iiqAnalyticsAnalyticsAdapter.initOptions.partner); result[PARAMS_NAMES.partnerId] = iiqAnalyticsAnalyticsAdapter.initOptions.partner; result[PARAMS_NAMES.prebidVersion] = prebidVersion; - result[PARAMS_NAMES.referrer] = generateVrrefValue(); - + result[PARAMS_NAMES.referrer] = getReferrer(); result[PARAMS_NAMES.terminationCause] = iiqAnalyticsAnalyticsAdapter.initOptions.terminationCause; result[PARAMS_NAMES.abTestGroup] = iiqAnalyticsAnalyticsAdapter.initOptions.currentGroup; @@ -273,7 +274,7 @@ function constructFullUrl(data) { '&source=pbjs' + '&payload=' + JSON.stringify(report) + '&uh=' + iiqAnalyticsAnalyticsAdapter.initOptions.clientsHints; - url = appendVrrefAndFui(url); + url = appendVrrefAndFui(url, iiqAnalyticsAnalyticsAdapter.initOptions.domainName); return url; } diff --git a/modules/intentIqIdSystem.js b/modules/intentIqIdSystem.js index 804aaa3b070..2a57f602973 100644 --- a/modules/intentIqIdSystem.js +++ b/modules/intentIqIdSystem.js @@ -385,7 +385,7 @@ export const intentIqIdSubmodule = { url += firstPartyData?.group ? '&testGroup=' + encodeURIComponent(firstPartyData.group) : ''; // Add vrref and fui to the URL - url = appendVrrefAndFui(url); + url = appendVrrefAndFui(url, configParams.domainName); const storeFirstPartyData = () => { partnerData.eidl = runtimeEids?.eids?.length || -1 From f0252b54e7bf5ca45ae9f2317fe9c0eaef052f2d Mon Sep 17 00:00:00 2001 From: dmytro-po Date: Fri, 1 Nov 2024 19:27:06 +0200 Subject: [PATCH 16/21] AGT-374: tests in progress --- libraries/intentIqUtils/getRefferer.js | 6 +-- modules/intentIqAnalyticsAdapter.js | 4 ++ .../modules/intentIqAnalyticsAdapter_spec.js | 45 ++++++++++++++++--- test/spec/modules/intentIqIdSystem_spec.js | 2 +- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/libraries/intentIqUtils/getRefferer.js b/libraries/intentIqUtils/getRefferer.js index f6a14d6b747..eb5f7a7b531 100644 --- a/libraries/intentIqUtils/getRefferer.js +++ b/libraries/intentIqUtils/getRefferer.js @@ -30,8 +30,8 @@ export function appendVrrefAndFui(url, domainName) { if (fullUrl) { return (url += '&vrref=' + getRelevantRefferer(domainName, fullUrl)); } - url += '&fui=1'; - if (domainName) url += '&vrref=' + encodeURIComponent(domainName); + url += '&fui=1'; // Full Url Issue + url += '&vrref=' + encodeURIComponent(domainName || ''); return url; } @@ -58,6 +58,6 @@ export function isDomainIncluded(fullUrl, domainName) { return fullUrl.includes(domainName); } catch (error) { logError(`Invalid URL provided: ${error}`); - return ''; + return false; } } diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index a3113b7b089..cc033d86ee5 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -288,4 +288,8 @@ adapterManager.registerAnalyticsAdapter({ code: MODULE_NAME }); +// for tests +iiqAnalyticsAnalyticsAdapter.constructRequestUrl = function(data) { + return constructFullUrl(data); +}; export default iiqAnalyticsAnalyticsAdapter; diff --git a/test/spec/modules/intentIqAnalyticsAdapter_spec.js b/test/spec/modules/intentIqAnalyticsAdapter_spec.js index dbc30202a2a..e40324bb302 100644 --- a/test/spec/modules/intentIqAnalyticsAdapter_spec.js +++ b/test/spec/modules/intentIqAnalyticsAdapter_spec.js @@ -1,15 +1,16 @@ import { expect } from 'chai'; import iiqAnalyticsAnalyticsAdapter from 'modules/intentIqAnalyticsAdapter.js'; import * as utils from 'src/utils.js'; -import * as detectBrowserUtils from '../../../libraries/intentIqUtils/detectBrowserUtils.js'; import { server } from 'test/mocks/xhr.js'; import { config } from 'src/config.js'; import { EVENTS } from 'src/constants.js'; import * as events from 'src/events.js'; import { getStorageManager } from 'src/storageManager.js'; import sinon from 'sinon'; -import { REPORTER_ID, getReferrer, preparePayload } from '../../../modules/intentIqAnalyticsAdapter'; +import { REPORTER_ID, preparePayload } from '../../../modules/intentIqAnalyticsAdapter'; import {FIRST_PARTY_KEY, VERSION} from '../../../libraries/intentIqConstants/intentIqConstants.js'; +import * as detectBrowserUtils from '../../../libraries/intentIqUtils/detectBrowserUtils.js'; +import {getReferrer, appendVrrefAndFui} from '../../../libraries/intentIqUtils/getRefferer.js'; const partner = 10; const defaultData = '{"pcid":"f961ffb1-a0e1-4696-a9d2-a21d815bd344", "group": "A"}'; @@ -63,7 +64,7 @@ let wonRequest = { 'pbDg': '5.00', 'pbCg': '', 'size': '728x90', - 'status': 'rendered' + 'status': 'rendered', }; describe('IntentIQ tests all', function () { @@ -89,7 +90,8 @@ describe('IntentIQ tests all', function () { dataInLs: null, eidl: null, lsIdsInitialized: false, - manualWinReportEnabled: false + manualWinReportEnabled: false, + domainName: null }; if (iiqAnalyticsAnalyticsAdapter.track.restore) { iiqAnalyticsAnalyticsAdapter.track.restore(); @@ -120,6 +122,9 @@ describe('IntentIQ tests all', function () { expect(server.requests.length).to.be.above(0); const request = server.requests[0]; + /* eslint no-console: "error" */ + // custom console + Console.log('analytics: ', request.url) expect(request.url).to.contain('https://reports.intentiq.com/report?pid=' + partner + '&mct=1'); expect(request.url).to.contain(`&jsver=${version}&vrref=${encodeURIComponent('http://localhost:9876/')}`); expect(request.url).to.contain('&payload='); @@ -250,8 +255,38 @@ describe('IntentIQ tests all', function () { expect(server.requests.length).to.be.above(0); const request = server.requests[0]; expect(request.url).to.contain(`https://reports.intentiq.com/report?pid=${partner}&mct=1`); - expect(request.url).to.contain(`&jsver=${version}&vrref=${encodeURIComponent('http://localhost:9876/')}`); + // expect(request.url).to.contain(`&jsver=${version}&vrref=${encodeURIComponent('http://localhost:9876/')}`);s expect(request.url).to.contain('&payload='); expect(request.url).to.contain('iiqid=f961ffb1-a0e1-4696-a9d2-a21d815bd344'); }); + + describe('IntentIQ vrref and fui logic', function () { + let getReferrerStub; + + afterEach(function() { + if (getReferrerStub) getReferrerStub.restore(); + }); + + it('should append vrref when referrer is available', function () { + getReferrerStub = sinon.stub(getReferrer, 'default').returns('http://localhost:9876/'); + const url = 'https://reports.intentiq.com/report?pid=10'; + const modifiedUrl = appendVrrefAndFui(url, 'example.com'); + const urlObj = new URL(modifiedUrl); + + const vrref = urlObj.searchParams.get('vrref'); + expect(vrref).to.equal(encodeURIComponent('http://localhost:9876/')); + expect(urlObj.searchParams.has('fui')).to.be.false; + }); + + it('should append fui=1 when referrer is unavailable', function () { + getReferrerStub = sinon.stub(getReferrer, 'default').returns(''); + + const url = 'https://reports.intentiq.com/report?pid=10'; + const modifiedUrl = appendVrrefAndFui(url, null); + const urlObj = new URL(modifiedUrl); + + const fui = urlObj.searchParams.get('fui'); + expect(fui).to.equal('1'); + }); + }); }); diff --git a/test/spec/modules/intentIqIdSystem_spec.js b/test/spec/modules/intentIqIdSystem_spec.js index cc3495aeb11..b2ce17470ff 100644 --- a/test/spec/modules/intentIqIdSystem_spec.js +++ b/test/spec/modules/intentIqIdSystem_spec.js @@ -5,7 +5,7 @@ import { server } from 'test/mocks/xhr.js'; import { decryptData, handleClientHints, handleGPPData, readData } from '../../../modules/intentIqIdSystem'; import { gppDataHandler, uspDataHandler } from '../../../src/consentHandler'; import { clearAllCookies } from '../../helpers/cookies'; -import { detectBrowserFromUserAgent, detectBrowserFromUserAgentData } from '../../../libraries/detectBrowserUtils/detectBrowserUtils'; +import { detectBrowserFromUserAgent, detectBrowserFromUserAgentData } from '../../../libraries/intentIqUtils/detectBrowserUtils'; import {CLIENT_HINTS_KEY, FIRST_PARTY_KEY} from '../../../libraries/intentIqConstants/intentIqConstants.js'; const partner = 10; From d949b885a8d7c1f8c40fa3680fcc3b5446188fd1 Mon Sep 17 00:00:00 2001 From: dmytro-po Date: Sun, 3 Nov 2024 16:21:19 +0200 Subject: [PATCH 17/21] AGT-374: Remove duplicate encoded in getRelevantRefferer and fix tests --- libraries/intentIqUtils/getRefferer.js | 7 +- .../modules/intentIqAnalyticsAdapter_spec.js | 84 ++++++++++++------- 2 files changed, 59 insertions(+), 32 deletions(-) diff --git a/libraries/intentIqUtils/getRefferer.js b/libraries/intentIqUtils/getRefferer.js index eb5f7a7b531..39fde70ac24 100644 --- a/libraries/intentIqUtils/getRefferer.js +++ b/libraries/intentIqUtils/getRefferer.js @@ -42,9 +42,10 @@ export function appendVrrefAndFui(url, domainName) { * @return {string} The relevant referrer */ export function getRelevantRefferer(domainName, fullUrl) { - return encodeURIComponent( - domainName && isDomainIncluded(fullUrl, domainName) ? fullUrl : domainName || fullUrl - ); + if (domainName && isDomainIncluded(fullUrl, domainName)) { + return fullUrl; + } + return domainName ? encodeURIComponent(domainName) : fullUrl; } /** diff --git a/test/spec/modules/intentIqAnalyticsAdapter_spec.js b/test/spec/modules/intentIqAnalyticsAdapter_spec.js index e40324bb302..a684d0a5a8d 100644 --- a/test/spec/modules/intentIqAnalyticsAdapter_spec.js +++ b/test/spec/modules/intentIqAnalyticsAdapter_spec.js @@ -117,16 +117,16 @@ describe('IntentIQ tests all', function () { it('IIQ Analytical Adapter bid win report', function () { localStorage.setItem(FIRST_PARTY_KEY, defaultData); + getWindowLocationStub = sinon.stub(utils, 'getWindowLocation').returns({href: 'http://localhost:9876/'}); + const expectedVrref = encodeURIComponent(getWindowLocationStub().href); events.emit(EVENTS.BID_WON, wonRequest); expect(server.requests.length).to.be.above(0); const request = server.requests[0]; - /* eslint no-console: "error" */ - // custom console - Console.log('analytics: ', request.url) expect(request.url).to.contain('https://reports.intentiq.com/report?pid=' + partner + '&mct=1'); - expect(request.url).to.contain(`&jsver=${version}&vrref=${encodeURIComponent('http://localhost:9876/')}`); + expect(request.url).to.contain(`&jsver=${version}`); + expect(request.url).to.contain(`&vrref=${expectedVrref}`); expect(request.url).to.contain('&payload='); expect(request.url).to.contain('iiqid=f961ffb1-a0e1-4696-a9d2-a21d815bd344'); }); @@ -137,13 +137,15 @@ describe('IntentIQ tests all', function () { it('should handle BID_WON event with group configuration from local storage', function () { localStorage.setItem(FIRST_PARTY_KEY, '{"pcid":"testpcid", "group": "B"}'); + const expectedVrref = encodeURIComponent('http://localhost:9876/'); events.emit(EVENTS.BID_WON, wonRequest); expect(server.requests.length).to.be.above(0); const request = server.requests[0]; expect(request.url).to.contain('https://reports.intentiq.com/report?pid=' + partner + '&mct=1'); - expect(request.url).to.contain(`&jsver=${version}&vrref=${encodeURIComponent('http://localhost:9876/')}`); + expect(request.url).to.contain(`&jsver=${version}`); + expect(request.url).to.contain(`&vrref=${expectedVrref}`); expect(request.url).to.contain('iiqid=testpcid'); }); @@ -158,9 +160,11 @@ describe('IntentIQ tests all', function () { const dataToSend = preparePayload(wonRequest); const base64String = btoa(JSON.stringify(dataToSend)); const payload = `[%22${base64String}%22]`; - expect(request.url).to.equal( - `https://reports.intentiq.com/report?pid=${partner}&mct=1&iiqid=${defaultDataObj.pcid}&agid=${REPORTER_ID}&jsver=${version}&vrref=${getReferrer()}&source=pbjs&payload=${payload}&uh=` + const expectedUrl = appendVrrefAndFui( + `https://reports.intentiq.com/report?pid=${partner}&mct=1&iiqid=${defaultDataObj.pcid}&agid=${REPORTER_ID}&jsver=${version}&source=pbjs&payload=${payload}&uh=`, + iiqAnalyticsAnalyticsAdapter.initOptions.domainName ); + expect(request.url).to.equal(expectedUrl); expect(dataToSend.pcid).to.equal(defaultDataObj.pcid) }); @@ -255,38 +259,60 @@ describe('IntentIQ tests all', function () { expect(server.requests.length).to.be.above(0); const request = server.requests[0]; expect(request.url).to.contain(`https://reports.intentiq.com/report?pid=${partner}&mct=1`); - // expect(request.url).to.contain(`&jsver=${version}&vrref=${encodeURIComponent('http://localhost:9876/')}`);s + expect(request.url).to.contain(`&jsver=${version}`); + expect(request.url).to.contain(`&vrref=${encodeURIComponent('http://localhost:9876/')}`); expect(request.url).to.contain('&payload='); expect(request.url).to.contain('iiqid=f961ffb1-a0e1-4696-a9d2-a21d815bd344'); }); - describe('IntentIQ vrref and fui logic', function () { - let getReferrerStub; - - afterEach(function() { - if (getReferrerStub) getReferrerStub.restore(); - }); - - it('should append vrref when referrer is available', function () { - getReferrerStub = sinon.stub(getReferrer, 'default').returns('http://localhost:9876/'); - const url = 'https://reports.intentiq.com/report?pid=10'; - const modifiedUrl = appendVrrefAndFui(url, 'example.com'); - const urlObj = new URL(modifiedUrl); - - const vrref = urlObj.searchParams.get('vrref'); - expect(vrref).to.equal(encodeURIComponent('http://localhost:9876/')); - expect(urlObj.searchParams.has('fui')).to.be.false; - }); + const testCasesVrref = [ + { + description: 'domainName matches window.top.location.href', + getWindowSelf: {}, + getWindowTop: { location: { href: 'http://example.com/page' } }, + getWindowLocation: { href: 'http://example.com/page' }, + domainName: 'example.com', + expectedVrref: encodeURIComponent('http://example.com/page'), + shouldContainFui: false + }, + { + description: 'domainName does not match window.top.location.href', + getWindowSelf: {}, + getWindowTop: { location: { href: 'http://anotherdomain.com/page' } }, + getWindowLocation: { href: 'http://anotherdomain.com/page' }, + domainName: 'example.com', + expectedVrref: encodeURIComponent('example.com'), + shouldContainFui: false + }, + { + description: 'domainName is missing, only fui=1 is returned', + getWindowSelf: {}, + getWindowTop: { location: { href: '' } }, + getWindowLocation: { href: '' }, + domainName: null, + expectedVrref: '', + shouldContainFui: true + } + ]; - it('should append fui=1 when referrer is unavailable', function () { - getReferrerStub = sinon.stub(getReferrer, 'default').returns(''); + testCasesVrref.forEach(({ description, getWindowSelf, getWindowTop, getWindowLocation, domainName, expectedVrref, shouldContainFui }) => { + it(`should append correct vrref when ${description}`, function () { + getWindowSelfStub = sinon.stub(utils, 'getWindowSelf').returns(getWindowSelf); + getWindowTopStub = sinon.stub(utils, 'getWindowTop').returns(getWindowTop); + getWindowLocationStub = sinon.stub(utils, 'getWindowLocation').returns(getWindowLocation); const url = 'https://reports.intentiq.com/report?pid=10'; - const modifiedUrl = appendVrrefAndFui(url, null); + const modifiedUrl = appendVrrefAndFui(url, domainName); const urlObj = new URL(modifiedUrl); + const vrref = encodeURIComponent(urlObj.searchParams.get('vrref') || ''); const fui = urlObj.searchParams.get('fui'); - expect(fui).to.equal('1'); + + expect(vrref).to.equal(expectedVrref); + expect(urlObj.searchParams.has('fui')).to.equal(shouldContainFui); + if (shouldContainFui) { + expect(fui).to.equal('1'); + } }); }); }); From 7eb4bcfaac8e4fc49b952e1e85313e7dc7471fc1 Mon Sep 17 00:00:00 2001 From: dmytro-po Date: Tue, 12 Nov 2024 09:26:20 +0200 Subject: [PATCH 18/21] AGT-374: Add test domainName, changes in documentation --- modules/intentIqIdSystem.md | 5 +++-- src/events.js | 1 - test/spec/modules/intentIqAnalyticsAdapter_spec.js | 11 ++++++++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/modules/intentIqIdSystem.md b/modules/intentIqIdSystem.md index 089fbeef509..34fd495d625 100644 --- a/modules/intentIqIdSystem.md +++ b/modules/intentIqIdSystem.md @@ -42,7 +42,7 @@ Please find below list of paramters that could be used in configuring Intent IQ | params.timeoutInMillis | Optional | Number | This is the timeout in milliseconds, which defines the maximum duration before the callback is triggered. The default value is 500. | `450` | | params.browserBlackList | Optional |  String | This is the name of a browser that can be added to a blacklist. | `"chrome"` | | params.manualWinReportEnabled | Optional | Boolean | This variable determines whether the bidWon event is triggered automatically. If set to false, the event will occur automatically, and manual reporting with reportExternalWin will be disabled. If set to true, the event will not occur automatically, allowing manual reporting through reportExternalWin. The default value is false. | `true`| - +| params.domainName | Optional | String | Specifies the domain of the page in which the IntentIQ object is currently running and serving the impression. This domain will be used later in the revenue reporting breakdown by domain. For example, cnn.com. It identifies the primary source of requests to the IntentIQ servers, even within nested web pages. | `"currentDomain.com"` | ### Configuration example @@ -56,7 +56,8 @@ pbjs.setConfig({ timeoutInMillis: 500, browserBlackList: "chrome", callback: (data, group) => window.pbjs.requestBids(), - manualWinReportEnabled: true + manualWinReportEnabled: true, + domainName: "currentDomain.com" }, storage: { type: "html5", diff --git a/src/events.js b/src/events.js index 279acc27b9a..38e7f633d16 100644 --- a/src/events.js +++ b/src/events.js @@ -161,7 +161,6 @@ const _public = (function () { return eventsFired.toArray().map(val => Object.assign({}, val)) }; - window.prebidEvents = _public return _public; }()); diff --git a/test/spec/modules/intentIqAnalyticsAdapter_spec.js b/test/spec/modules/intentIqAnalyticsAdapter_spec.js index a684d0a5a8d..8822e24f269 100644 --- a/test/spec/modules/intentIqAnalyticsAdapter_spec.js +++ b/test/spec/modules/intentIqAnalyticsAdapter_spec.js @@ -292,7 +292,16 @@ describe('IntentIQ tests all', function () { domainName: null, expectedVrref: '', shouldContainFui: true - } + }, + { + description: 'domainName is missing', + getWindowSelf: {}, + getWindowTop: { location: { href: 'http://example.com/page' } }, + getWindowLocation: { href: 'http://example.com/page' }, + domainName: null, + expectedVrref: encodeURIComponent('http://example.com/page'), + shouldContainFui: false + }, ]; testCasesVrref.forEach(({ description, getWindowSelf, getWindowTop, getWindowLocation, domainName, expectedVrref, shouldContainFui }) => { From 2d709b59b04aebf1ab3c53142844367b0b297252 Mon Sep 17 00:00:00 2001 From: dmytro-po Date: Tue, 12 Nov 2024 09:32:03 +0200 Subject: [PATCH 19/21] AGT-374: Change js version value --- libraries/intentIqConstants/intentIqConstants.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/intentIqConstants/intentIqConstants.js b/libraries/intentIqConstants/intentIqConstants.js index 46c466e936f..56f014be4c1 100644 --- a/libraries/intentIqConstants/intentIqConstants.js +++ b/libraries/intentIqConstants/intentIqConstants.js @@ -7,4 +7,4 @@ export const OPT_OUT = 'O'; export const BLACK_LIST = 'L'; export const CLIENT_HINTS_KEY = '_iiq_ch'; export const EMPTY = 'EMPTY' -export const VERSION = 0.21 +export const VERSION = 0.22 From 21c758bd1308cb0f9117ad97e42ecac6ed653bca Mon Sep 17 00:00:00 2001 From: dmytro-po Date: Tue, 12 Nov 2024 10:05:54 +0200 Subject: [PATCH 20/21] AGT-374: Remove extra coma --- test/spec/modules/intentIqAnalyticsAdapter_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spec/modules/intentIqAnalyticsAdapter_spec.js b/test/spec/modules/intentIqAnalyticsAdapter_spec.js index 8822e24f269..5ba0686af0b 100644 --- a/test/spec/modules/intentIqAnalyticsAdapter_spec.js +++ b/test/spec/modules/intentIqAnalyticsAdapter_spec.js @@ -64,7 +64,7 @@ let wonRequest = { 'pbDg': '5.00', 'pbCg': '', 'size': '728x90', - 'status': 'rendered', + 'status': 'rendered' }; describe('IntentIQ tests all', function () { From c86bcd280aed1963fe671fccb561ac600e0d8825 Mon Sep 17 00:00:00 2001 From: dmytro-po Date: Tue, 12 Nov 2024 10:33:33 +0200 Subject: [PATCH 21/21] Remove unused method --- modules/intentIqAnalyticsAdapter.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index cc033d86ee5..a3113b7b089 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -288,8 +288,4 @@ adapterManager.registerAnalyticsAdapter({ code: MODULE_NAME }); -// for tests -iiqAnalyticsAnalyticsAdapter.constructRequestUrl = function(data) { - return constructFullUrl(data); -}; export default iiqAnalyticsAnalyticsAdapter;