From 7eaa5c28e01f284f7dbd530c247703434d0641d1 Mon Sep 17 00:00:00 2001 From: dmytro-po Date: Fri, 16 Jan 2026 16:22:38 +0200 Subject: [PATCH 1/3] AGT-765: pos and size --- libraries/intentIqUtils/resolvePosFromPbjs.js | 17 +++++++++++++++++ modules/intentIqAnalyticsAdapter.js | 12 ++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 libraries/intentIqUtils/resolvePosFromPbjs.js diff --git a/libraries/intentIqUtils/resolvePosFromPbjs.js b/libraries/intentIqUtils/resolvePosFromPbjs.js new file mode 100644 index 00000000000..989dc59055d --- /dev/null +++ b/libraries/intentIqUtils/resolvePosFromPbjs.js @@ -0,0 +1,17 @@ +export function resolvePosFromPbjs(pbjs, adUnitCode) { + const adUnits = pbjs?.adUnits; + if (!Array.isArray(adUnits) || !adUnitCode) return; + + for (let i = 0; i < adUnits.length; i++) { + const adUnit = adUnits[i]; + if (adUnit?.code !== adUnitCode) continue; + + const mediaTypes = adUnit?.mediaTypes; + if (!mediaTypes || typeof mediaTypes !== 'object') return; + + const firstKey = Object.keys(mediaTypes)[0]; + const pos = mediaTypes[firstKey]?.pos; + + return typeof pos === 'number' ? pos : undefined; + } +} diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index 03f1aa65654..363715c308e 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -7,6 +7,7 @@ import { detectBrowser } from '../libraries/intentIqUtils/detectBrowserUtils.js' import { appendSPData } from '../libraries/intentIqUtils/urlUtils.js'; import { appendVrrefAndFui, getReferrer } from '../libraries/intentIqUtils/getRefferer.js'; import { getCmpData } from '../libraries/intentIqUtils/getCmpData.js'; +import { resolvePosFromPbjs } from '../libraries/intentIqUtils/resolvePosFromPbjs.js'; import { VERSION, PREBID, @@ -16,10 +17,12 @@ import { reportingServerAddress } from '../libraries/intentIqUtils/intentIqConfi import { handleAdditionalParams } from '../libraries/intentIqUtils/handleAdditionalParams.js'; import { gamPredictionReport } from '../libraries/intentIqUtils/gamPredictionReport.js'; import { defineABTestingGroup } from '../libraries/intentIqUtils/defineABTestingGroupUtils.js'; +import { getGlobal } from '../src/prebidGlobal.js'; const MODULE_NAME = 'iiqAnalytics'; const analyticsType = 'endpoint'; const prebidVersion = '$prebid.version$'; +const pbjs = getGlobal(); export const REPORTER_ID = Date.now() + '_' + getRandom(0, 1000); let globalName; let identityGlobalName; @@ -344,6 +347,15 @@ function prepareData(data, result) { if (data.status) { result.status = data.status; } + if (data.size) { + result.size = data.size; + } + if (typeof data.pos === 'number') { + result.pos = data.pos; + } else if (data.adUnitCode) { + const pos = resolvePosFromPbjs(pbjs, data.adUnitCode); + if (typeof pos === 'number') result.pos = pos; + } result.prebidAuctionId = data.auctionId || data.prebidAuctionId; From 55c31d72e1d128e4541b8c5809bcf1a6993e4deb Mon Sep 17 00:00:00 2001 From: dmytro-po Date: Mon, 19 Jan 2026 13:12:25 +0200 Subject: [PATCH 2/3] AGT-765: Tests for position resolving --- ...solvePosFromPbjs.js => getUnitPosition.js} | 2 +- modules/intentIqAnalyticsAdapter.js | 4 +- .../modules/intentIqAnalyticsAdapter_spec.js | 42 +++++++++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) rename libraries/intentIqUtils/{resolvePosFromPbjs.js => getUnitPosition.js} (89%) diff --git a/libraries/intentIqUtils/resolvePosFromPbjs.js b/libraries/intentIqUtils/getUnitPosition.js similarity index 89% rename from libraries/intentIqUtils/resolvePosFromPbjs.js rename to libraries/intentIqUtils/getUnitPosition.js index 989dc59055d..025a06a9964 100644 --- a/libraries/intentIqUtils/resolvePosFromPbjs.js +++ b/libraries/intentIqUtils/getUnitPosition.js @@ -1,4 +1,4 @@ -export function resolvePosFromPbjs(pbjs, adUnitCode) { +export function getUnitPosition(pbjs, adUnitCode) { const adUnits = pbjs?.adUnits; if (!Array.isArray(adUnits) || !adUnitCode) return; diff --git a/modules/intentIqAnalyticsAdapter.js b/modules/intentIqAnalyticsAdapter.js index 363715c308e..1f59d0b403e 100644 --- a/modules/intentIqAnalyticsAdapter.js +++ b/modules/intentIqAnalyticsAdapter.js @@ -7,7 +7,7 @@ import { detectBrowser } from '../libraries/intentIqUtils/detectBrowserUtils.js' import { appendSPData } from '../libraries/intentIqUtils/urlUtils.js'; import { appendVrrefAndFui, getReferrer } from '../libraries/intentIqUtils/getRefferer.js'; import { getCmpData } from '../libraries/intentIqUtils/getCmpData.js'; -import { resolvePosFromPbjs } from '../libraries/intentIqUtils/resolvePosFromPbjs.js'; +import { getUnitPosition } from '../libraries/intentIqUtils/getUnitPosition.js'; import { VERSION, PREBID, @@ -353,7 +353,7 @@ function prepareData(data, result) { if (typeof data.pos === 'number') { result.pos = data.pos; } else if (data.adUnitCode) { - const pos = resolvePosFromPbjs(pbjs, data.adUnitCode); + const pos = getUnitPosition(pbjs, data.adUnitCode); if (typeof pos === 'number') result.pos = pos; } diff --git a/test/spec/modules/intentIqAnalyticsAdapter_spec.js b/test/spec/modules/intentIqAnalyticsAdapter_spec.js index c103aff65a0..01646765626 100644 --- a/test/spec/modules/intentIqAnalyticsAdapter_spec.js +++ b/test/spec/modules/intentIqAnalyticsAdapter_spec.js @@ -5,6 +5,7 @@ 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 { getGlobal } from "../../../src/prebidGlobal.js"; import sinon from "sinon"; import { REPORTER_ID, @@ -319,6 +320,47 @@ describe("IntentIQ tests all", function () { expect(payloadDecoded).to.have.property("adType", externalWinEvent.adType); }); + it("should resolve pos from pbjs.adUnits when BID_WON has no pos", function () { + const pbjs = getGlobal(); + const prevAdUnits = pbjs.adUnits; + + pbjs.adUnits = Array.isArray(pbjs.adUnits) ? pbjs.adUnits : []; + pbjs.adUnits.push({ code: "myVideoAdUnit", mediaTypes: { video: { pos: 777 } } }); + + enableAnalyticWithSpecialOptions({ manualWinReportEnabled: false }); + + events.emit(EVENTS.BID_WON, { + ...getWonRequest(), + adUnitCode: "myVideoAdUnit", + mediaType: "video" + }); + + const request = server.requests[0]; + const payloadEncoded = new URL(request.url).searchParams.get("payload"); + const payloadDecoded = JSON.parse(atob(JSON.parse(payloadEncoded)[0])); + + expect(payloadDecoded.pos).to.equal(777); + + pbjs.adUnits = prevAdUnits; + }); + + it("should resolve pos from BID_WON event when present", function () { + const bidWonPos = 999; + enableAnalyticWithSpecialOptions({ manualWinReportEnabled: false }); + + events.emit(EVENTS.BID_WON, { + ...getWonRequest(), + mediaType: "video", + pos: bidWonPos + }); + + const request = server.requests[0]; + const payloadEncoded = new URL(request.url).searchParams.get("payload"); + const payloadDecoded = JSON.parse(atob(JSON.parse(payloadEncoded)[0])); + + expect(payloadDecoded.pos).to.equal(bidWonPos); + }); + // it("should send report to report-gdpr address if gdpr is detected", function () { // const gppStub = sinon // .stub(gppDataHandler, "getConsentData") From 79bdd9dce127b2904febe9af1f4b2c93f456db9e Mon Sep 17 00:00:00 2001 From: dmytro-po Date: Mon, 19 Jan 2026 15:33:15 +0200 Subject: [PATCH 3/3] AGT-765: Test fix --- .../modules/intentIqAnalyticsAdapter_spec.js | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/test/spec/modules/intentIqAnalyticsAdapter_spec.js b/test/spec/modules/intentIqAnalyticsAdapter_spec.js index 01646765626..529b1ed7b7e 100644 --- a/test/spec/modules/intentIqAnalyticsAdapter_spec.js +++ b/test/spec/modules/intentIqAnalyticsAdapter_spec.js @@ -320,7 +320,7 @@ describe("IntentIQ tests all", function () { expect(payloadDecoded).to.have.property("adType", externalWinEvent.adType); }); - it("should resolve pos from pbjs.adUnits when BID_WON has no pos", function () { + it("should get pos from pbjs.adUnits when BID_WON has no pos", function () { const pbjs = getGlobal(); const prevAdUnits = pbjs.adUnits; @@ -344,21 +344,28 @@ describe("IntentIQ tests all", function () { pbjs.adUnits = prevAdUnits; }); - it("should resolve pos from BID_WON event when present", function () { - const bidWonPos = 999; - enableAnalyticWithSpecialOptions({ manualWinReportEnabled: false }); + it("should get pos from reportExternalWin when present", function () { + enableAnalyticWithSpecialOptions({ manualWinReportEnabled: true }); - events.emit(EVENTS.BID_WON, { - ...getWonRequest(), + const winPos = 999; + + window[`intentIqAnalyticsAdapter_${partner}`].reportExternalWin({ + adUnitCode: "myVideoAdUnit", + bidderCode: "appnexus", + cpm: 1.5, + currency: "USD", mediaType: "video", - pos: bidWonPos + size: "300x250", + status: "rendered", + auctionId: "auc123", + pos: winPos }); const request = server.requests[0]; const payloadEncoded = new URL(request.url).searchParams.get("payload"); const payloadDecoded = JSON.parse(atob(JSON.parse(payloadEncoded)[0])); - expect(payloadDecoded.pos).to.equal(bidWonPos); + expect(payloadDecoded.pos).to.equal(winPos); }); // it("should send report to report-gdpr address if gdpr is detected", function () {