From f625c1e916986275297f53c92c234468834e69b3 Mon Sep 17 00:00:00 2001 From: Konstantin Korobkov Date: Wed, 27 Dec 2023 18:22:50 +0100 Subject: [PATCH] Yandex Bid Adapter: Add rtt (roud trip time) tracking via nurl (#10846) * Add rtt (roud trip time) tracking via nurl in yandexBidAdapter * Yandex Bid Adapter: Fix let -> const --------- Co-authored-by: Konstantin Korobkov --- modules/yandexBidAdapter.js | 22 ++++++++- test/spec/modules/yandexBidAdapter_spec.js | 55 ++++++++++++++++++++-- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/modules/yandexBidAdapter.js b/modules/yandexBidAdapter.js index 9ca989b2259..4a7f9114a17 100644 --- a/modules/yandexBidAdapter.js +++ b/modules/yandexBidAdapter.js @@ -147,7 +147,7 @@ export const spec = { interpretResponse: interpretResponse, onBidWon: function (bid) { - const nurl = bid['nurl']; + const nurl = addRTT(bid['nurl'], bid.timeToRespond); if (!nurl) { return; @@ -385,4 +385,24 @@ function replaceAuctionPrice(url, price, currency) { .replace(/\${AUCTION_CURRENCY}/, currency); } +function addRTT(url, rtt) { + if (!url) return; + + if (url.indexOf(`\${RTT}`) > -1) { + return url.replace(/\${RTT}/, rtt ?? -1); + } + + const urlObj = new URL(url); + + if (Number.isInteger(rtt)) { + urlObj.searchParams.set('rtt', rtt); + } else { + urlObj.searchParams.delete('rtt'); + } + + url = urlObj.toString(); + + return url; +} + registerBidder(spec); diff --git a/test/spec/modules/yandexBidAdapter_spec.js b/test/spec/modules/yandexBidAdapter_spec.js index f14e8df6c09..d5cfc26b31a 100644 --- a/test/spec/modules/yandexBidAdapter_spec.js +++ b/test/spec/modules/yandexBidAdapter_spec.js @@ -1,6 +1,6 @@ import { assert, expect } from 'chai'; import { spec, NATIVE_ASSETS } from 'modules/yandexBidAdapter.js'; -import { parseUrl } from 'src/utils.js'; +import * as utils from 'src/utils.js'; import { BANNER, NATIVE } from '../../../src/mediaTypes'; import { config } from '../../../src/config'; @@ -71,7 +71,7 @@ describe('Yandex adapter', function () { expect(method).to.equal('POST'); - const parsedRequestUrl = parseUrl(url); + const parsedRequestUrl = utils.parseUrl(url); const { search: query } = parsedRequestUrl expect(parsedRequestUrl.hostname).to.equal('bs.yandex.ru'); @@ -100,7 +100,7 @@ describe('Yandex adapter', function () { const bannerRequest = getBidRequest(); const requests = spec.buildRequests([bannerRequest], bidderRequest); const { url } = requests[0]; - const parsedRequestUrl = parseUrl(url); + const parsedRequestUrl = utils.parseUrl(url); const { search: query } = parsedRequestUrl expect(query['ssp-cur']).to.equal('USD'); @@ -478,6 +478,55 @@ describe('Yandex adapter', function () { }); }); }); + + describe('onBidWon', function() { + beforeEach(function() { + sinon.stub(utils, 'triggerPixel'); + }); + afterEach(function() { + utils.triggerPixel.restore(); + }); + + it('Should not trigger pixel if bid does not contain nurl', function() { + const result = spec.onBidWon({}); + expect(utils.triggerPixel.callCount).to.equal(0) + }) + + it('Should trigger pixel if bid has nurl', function() { + const result = spec.onBidWon({ + nurl: 'https://example.com/some-tracker', + timeToRespond: 378, + }); + expect(utils.triggerPixel.callCount).to.equal(1) + expect(utils.triggerPixel.getCall(0).args[0]).to.equal('https://example.com/some-tracker?rtt=378') + }) + + it('Should trigger pixel if bid has nurl with path & params', function() { + const result = spec.onBidWon({ + nurl: 'https://example.com/some-tracker/abcdxyz?param1=1¶m2=2', + timeToRespond: 378, + }); + expect(utils.triggerPixel.callCount).to.equal(1) + expect(utils.triggerPixel.getCall(0).args[0]).to.equal('https://example.com/some-tracker/abcdxyz?param1=1¶m2=2&rtt=378') + }) + + it('Should trigger pixel if bid has nurl with path & params and rtt macros', function() { + const result = spec.onBidWon({ + nurl: 'https://example.com/some-tracker/abcdxyz?param1=1¶m2=2&custom-rtt=${RTT}', + timeToRespond: 378, + }); + expect(utils.triggerPixel.callCount).to.equal(1) + expect(utils.triggerPixel.getCall(0).args[0]).to.equal('https://example.com/some-tracker/abcdxyz?param1=1¶m2=2&custom-rtt=378') + }) + + it('Should trigger pixel if bid has nurl and there is no timeToRespond param, but has rtt macros in nurl', function() { + const result = spec.onBidWon({ + nurl: 'https://example.com/some-tracker/abcdxyz?param1=1¶m2=2&custom-rtt=${RTT}', + }); + expect(utils.triggerPixel.callCount).to.equal(1) + expect(utils.triggerPixel.getCall(0).args[0]).to.equal('https://example.com/some-tracker/abcdxyz?param1=1¶m2=2&custom-rtt=-1') + }) + }) }); function getBidConfig() {