From 0ef01016ab44fdfa8ef835848d3a9bdef5d5bd48 Mon Sep 17 00:00:00 2001 From: Yohan Boutin Date: Fri, 20 Oct 2023 15:11:04 +0200 Subject: [PATCH 1/6] add adunit geometry parameter to the bid request --- modules/seedtagBidAdapter.js | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/modules/seedtagBidAdapter.js b/modules/seedtagBidAdapter.js index 7ac7d048c50..651c20f67f2 100644 --- a/modules/seedtagBidAdapter.js +++ b/modules/seedtagBidAdapter.js @@ -107,7 +107,6 @@ function buildBidRequest(validBidRequest) { return mediaTypesMap[pbjsType]; } ); - const bidRequest = { id: validBidRequest.bidId, transactionId: validBidRequest.ortb2Imp?.ext?.tid, @@ -115,6 +114,7 @@ function buildBidRequest(validBidRequest) { supplyTypes: mediaTypes, adUnitId: params.adUnitId, adUnitCode: validBidRequest.adUnitCode, + geom: geom(validBidRequest.adUnitCode), placement: params.placement, requestCount: validBidRequest.bidderRequestsCount || 1, // FIXME : in unit test the parameter bidderRequestsCount is undefined }; @@ -198,6 +198,27 @@ function ttfb() { return ttfb >= 0 && ttfb <= performance.now() ? ttfb : 0; } +function geom(adunitCode) { + const slot = document.getElementById(adunitCode); + if (slot) { + const scrollY = window.scrollY; + const { top, left, width, height } = slot.getBoundingClientRect(); + const viewport = { + width: window.innerWidth, + height: window.innerHeight, + }; + + return { + scrollY, + top, + left, + width, + height, + viewport, + }; + } +} + export function getTimeoutUrl(data) { let queryParams = ''; if ( @@ -277,13 +298,13 @@ export const spec = { if (bidderRequest.gppConsent) { payload.gppConsent = { gppString: bidderRequest.gppConsent.gppString, - applicableSections: bidderRequest.gppConsent.applicableSections - } + applicableSections: bidderRequest.gppConsent.applicableSections, + }; } else if (bidderRequest.ortb2?.regs?.gpp) { payload.gppConsent = { gppString: bidderRequest.ortb2.regs.gpp, - applicableSections: bidderRequest.ortb2.regs.gpp_sid - } + applicableSections: bidderRequest.ortb2.regs.gpp_sid, + }; } const payloadString = JSON.stringify(payload); From f531b8b94429af91d58c7e3b522470cc1c7523c1 Mon Sep 17 00:00:00 2001 From: Yohan Boutin Date: Fri, 5 Jan 2024 15:26:53 +0100 Subject: [PATCH 2/6] lint --- modules/seedtagBidAdapter.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/seedtagBidAdapter.js b/modules/seedtagBidAdapter.js index 651c20f67f2..51c326c2954 100644 --- a/modules/seedtagBidAdapter.js +++ b/modules/seedtagBidAdapter.js @@ -298,13 +298,13 @@ export const spec = { if (bidderRequest.gppConsent) { payload.gppConsent = { gppString: bidderRequest.gppConsent.gppString, - applicableSections: bidderRequest.gppConsent.applicableSections, - }; + applicableSections: bidderRequest.gppConsent.applicableSections + } } else if (bidderRequest.ortb2?.regs?.gpp) { payload.gppConsent = { gppString: bidderRequest.ortb2.regs.gpp, - applicableSections: bidderRequest.ortb2.regs.gpp_sid, - }; + applicableSections: bidderRequest.ortb2.regs.gpp_sid + } } const payloadString = JSON.stringify(payload); From 1040c68b617f0cdfe85b7be0ba951f361819085f Mon Sep 17 00:00:00 2001 From: Yohan Boutin Date: Fri, 5 Jan 2024 16:55:59 +0100 Subject: [PATCH 3/6] add unit test --- test/spec/modules/seedtagBidAdapter_spec.js | 41 ++++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/test/spec/modules/seedtagBidAdapter_spec.js b/test/spec/modules/seedtagBidAdapter_spec.js index fb666e89f73..51414e62798 100644 --- a/test/spec/modules/seedtagBidAdapter_spec.js +++ b/test/spec/modules/seedtagBidAdapter_spec.js @@ -2,10 +2,13 @@ import { expect } from 'chai'; import { spec, getTimeoutUrl } from 'modules/seedtagBidAdapter.js'; import * as utils from 'src/utils.js'; import { config } from '../../../src/config.js'; +import * as mockGpt from 'test/spec/integration/faker/googletag.js'; const PUBLISHER_ID = '0000-0000-01'; const ADUNIT_ID = '000000'; +const adUnitCode = '/19968336/header-bid-tag-0' + function getSlotConfigs(mediaTypes, params) { return { params: params, @@ -25,7 +28,7 @@ function getSlotConfigs(mediaTypes, params) { tid: 'd704d006-0d6e-4a09-ad6c-179e7e758096', } }, - adUnitCode: 'adunit-code', + adUnitCode: adUnitCode, }; } @@ -45,7 +48,20 @@ const createBannerSlotConfig = (placement, mediatypes) => { }); }; + + describe('Seedtag Adapter', function () { + beforeEach(function () { + // create the adunit slot + const slot = document.createElement('div'); + slot.id = adUnitCode; + document.body.appendChild(slot); + mockGpt.reset(); + }); + + afterEach(function () { + mockGpt.enable(); + }); describe('isBidRequestValid method', function () { describe('returns true', function () { describe('when banner slot config has all mandatory params', () => { @@ -277,7 +293,7 @@ describe('Seedtag Adapter', function () { expect(data.auctionStart).to.be.greaterThanOrEqual(now); expect(data.ttfb).to.be.greaterThanOrEqual(0); - expect(data.bidRequests[0].adUnitCode).to.equal('adunit-code'); + expect(data.bidRequests[0].adUnitCode).to.equal(adUnitCode); }); describe('GDPR params', function () { @@ -374,6 +390,27 @@ describe('Seedtag Adapter', function () { expect(videoBid.sizes[1][1]).to.equal(600); expect(videoBid.requestCount).to.equal(1); }); + + it('should have geom parameters if slot is available', function() { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const data = JSON.parse(request.data); + const bidRequests = data.bidRequests; + const bannerBid = bidRequests[0]; + expect(bannerBid).to.have.property('geom') + + const params = ['top', 'left', 'width', 'height', 'scrollY'] + params.forEach(param => { + expect(bannerBid.geom).to.have.property(param) + expect(bannerBid.geom[param]).to.be.a('number') + }) + + expect(bannerBid.geom).to.have.property('viewport') + const viewportParams = ['width', 'height'] + viewportParams.forEach(param => { + expect(bannerBid.geom.viewport).to.have.property(param) + expect(bannerBid.geom.viewport[param]).to.be.a('number') + }) + }) }); describe('COPPA param', function () { From 669af345b0e1c0968e92f3fd0192bbbddb641ceb Mon Sep 17 00:00:00 2001 From: Yohan Boutin Date: Fri, 5 Jan 2024 17:15:55 +0100 Subject: [PATCH 4/6] add size check --- test/spec/modules/seedtagBidAdapter_spec.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/test/spec/modules/seedtagBidAdapter_spec.js b/test/spec/modules/seedtagBidAdapter_spec.js index 51414e62798..17b196acbdf 100644 --- a/test/spec/modules/seedtagBidAdapter_spec.js +++ b/test/spec/modules/seedtagBidAdapter_spec.js @@ -48,13 +48,17 @@ const createBannerSlotConfig = (placement, mediatypes) => { }); }; - - describe('Seedtag Adapter', function () { beforeEach(function () { // create the adunit slot const slot = document.createElement('div'); slot.id = adUnitCode; + slot.style.width = '300px' + slot.style.height = '250px' + slot.style.position = 'absolute' + slot.style.top = '10px' + slot.style.left = '20px' + document.body.appendChild(slot); mockGpt.reset(); }); @@ -398,10 +402,11 @@ describe('Seedtag Adapter', function () { const bannerBid = bidRequests[0]; expect(bannerBid).to.have.property('geom') - const params = ['top', 'left', 'width', 'height', 'scrollY'] - params.forEach(param => { + const params = [['width', 300], ['height', 250], ['top', 10], ['left', 20], ['scrollY', 0]] + params.forEach(([param, value]) => { expect(bannerBid.geom).to.have.property(param) expect(bannerBid.geom[param]).to.be.a('number') + expect(bannerBid.geom[param]).to.be.equal(value) }) expect(bannerBid.geom).to.have.property('viewport') From 3fe69817aae642fdae65f1568fdb2fbaf69cfe2f Mon Sep 17 00:00:00 2001 From: Yohan Boutin Date: Fri, 5 Jan 2024 17:44:12 +0100 Subject: [PATCH 5/6] use global slot for all tests --- test/spec/modules/seedtagBidAdapter_spec.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/test/spec/modules/seedtagBidAdapter_spec.js b/test/spec/modules/seedtagBidAdapter_spec.js index 17b196acbdf..0767384576c 100644 --- a/test/spec/modules/seedtagBidAdapter_spec.js +++ b/test/spec/modules/seedtagBidAdapter_spec.js @@ -9,6 +9,17 @@ const ADUNIT_ID = '000000'; const adUnitCode = '/19968336/header-bid-tag-0' +// create a default adunit +const slot = document.createElement('div'); +slot.id = adUnitCode; +slot.style.width = '300px' +slot.style.height = '250px' +slot.style.position = 'absolute' +slot.style.top = '10px' +slot.style.left = '20px' + +document.body.appendChild(slot); + function getSlotConfigs(mediaTypes, params) { return { params: params, @@ -50,16 +61,6 @@ const createBannerSlotConfig = (placement, mediatypes) => { describe('Seedtag Adapter', function () { beforeEach(function () { - // create the adunit slot - const slot = document.createElement('div'); - slot.id = adUnitCode; - slot.style.width = '300px' - slot.style.height = '250px' - slot.style.position = 'absolute' - slot.style.top = '10px' - slot.style.left = '20px' - - document.body.appendChild(slot); mockGpt.reset(); }); From 32dc35455fe9a9817dd96fd9fdfdcdbc6d625112 Mon Sep 17 00:00:00 2001 From: Yohan Boutin Date: Tue, 9 Jan 2024 10:12:40 +0100 Subject: [PATCH 6/6] fix test when slot is not available$ --- test/spec/modules/seedtagBidAdapter_spec.js | 37 ++++++++++++--------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/test/spec/modules/seedtagBidAdapter_spec.js b/test/spec/modules/seedtagBidAdapter_spec.js index 0767384576c..516c5ec933a 100644 --- a/test/spec/modules/seedtagBidAdapter_spec.js +++ b/test/spec/modules/seedtagBidAdapter_spec.js @@ -401,21 +401,28 @@ describe('Seedtag Adapter', function () { const data = JSON.parse(request.data); const bidRequests = data.bidRequests; const bannerBid = bidRequests[0]; - expect(bannerBid).to.have.property('geom') - - const params = [['width', 300], ['height', 250], ['top', 10], ['left', 20], ['scrollY', 0]] - params.forEach(([param, value]) => { - expect(bannerBid.geom).to.have.property(param) - expect(bannerBid.geom[param]).to.be.a('number') - expect(bannerBid.geom[param]).to.be.equal(value) - }) - - expect(bannerBid.geom).to.have.property('viewport') - const viewportParams = ['width', 'height'] - viewportParams.forEach(param => { - expect(bannerBid.geom.viewport).to.have.property(param) - expect(bannerBid.geom.viewport[param]).to.be.a('number') - }) + + // on some CI, the DOM is not initialized, so we need to check if the slot is available + const slot = document.getElementById(adUnitCode) + if (slot) { + expect(bannerBid).to.have.property('geom') + + const params = [['width', 300], ['height', 250], ['top', 10], ['left', 20], ['scrollY', 0]] + params.forEach(([param, value]) => { + expect(bannerBid.geom).to.have.property(param) + expect(bannerBid.geom[param]).to.be.a('number') + expect(bannerBid.geom[param]).to.be.equal(value) + }) + + expect(bannerBid.geom).to.have.property('viewport') + const viewportParams = ['width', 'height'] + viewportParams.forEach(param => { + expect(bannerBid.geom.viewport).to.have.property(param) + expect(bannerBid.geom.viewport[param]).to.be.a('number') + }) + } else { + expect(bannerBid).to.not.have.property('geom') + } }) });