diff --git a/libraries/intentIqUtils/getUnitPosition.js b/libraries/intentIqUtils/getUnitPosition.js new file mode 100644 index 00000000000..025a06a9964 --- /dev/null +++ b/libraries/intentIqUtils/getUnitPosition.js @@ -0,0 +1,17 @@ +export function getUnitPosition(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..1f59d0b403e 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 { getUnitPosition } from '../libraries/intentIqUtils/getUnitPosition.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 = getUnitPosition(pbjs, data.adUnitCode); + if (typeof pos === 'number') result.pos = pos; + } result.prebidAuctionId = data.auctionId || data.prebidAuctionId; diff --git a/test/spec/modules/intentIqAnalyticsAdapter_spec.js b/test/spec/modules/intentIqAnalyticsAdapter_spec.js index c103aff65a0..529b1ed7b7e 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,54 @@ describe("IntentIQ tests all", function () { expect(payloadDecoded).to.have.property("adType", externalWinEvent.adType); }); + it("should get 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 get pos from reportExternalWin when present", function () { + enableAnalyticWithSpecialOptions({ manualWinReportEnabled: true }); + + const winPos = 999; + + window[`intentIqAnalyticsAdapter_${partner}`].reportExternalWin({ + adUnitCode: "myVideoAdUnit", + bidderCode: "appnexus", + cpm: 1.5, + currency: "USD", + mediaType: "video", + 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(winPos); + }); + // it("should send report to report-gdpr address if gdpr is detected", function () { // const gppStub = sinon // .stub(gppDataHandler, "getConsentData")