diff --git a/modules/undertoneBidAdapter.js b/modules/undertoneBidAdapter.js index a253c6aae5f..923e54183ab 100644 --- a/modules/undertoneBidAdapter.js +++ b/modules/undertoneBidAdapter.js @@ -51,6 +51,26 @@ function getGdprQueryParams(gdprConsent) { return `gdpr=${gdpr}&gdprstr=${gdprstr}`; } +function getBannerCoords(id) { + let element = document.getElementById(id); + let left = -1; + let top = -1; + if (element) { + left = element.offsetLeft; + top = element.offsetTop; + + let parent = element.offsetParent; + if (parent) { + left += parent.offsetLeft; + top += parent.offsetTop; + } + + return [left, top]; + } else { + return null; + } +} + export const spec = { code: BIDDER_CODE, isBidRequestValid: function(bid) { @@ -60,11 +80,15 @@ export const spec = { } }, buildRequests: function(validBidRequests, bidderRequest) { + const vw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); + const vh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); + const pageSizeArray = vw == 0 || vh == 0 ? null : [vw, vh]; const payload = { 'x-ut-hb-params': [], 'commons': { 'adapterVersion': '$prebid.version$', - 'uids': validBidRequests[0].userId + 'uids': validBidRequests[0].userId, + 'pageSize': pageSizeArray } }; const referer = bidderRequest.refererInfo.referer; @@ -87,6 +111,7 @@ export const spec = { validBidRequests.map(bidReq => { const bid = { bidRequestId: bidReq.bidId, + coordinates: getBannerCoords(bidReq.adUnitCode), hbadaptor: 'prebid', url: pageUrl, domain: domain, diff --git a/test/spec/modules/undertoneBidAdapter_spec.js b/test/spec/modules/undertoneBidAdapter_spec.js index f379081f88d..e4218019e0d 100644 --- a/test/spec/modules/undertoneBidAdapter_spec.js +++ b/test/spec/modules/undertoneBidAdapter_spec.js @@ -25,6 +25,7 @@ const invalidBidReq = { }; const bidReq = [{ + adUnitCode: 'div-gpt-ad-1460505748561-0', bidder: BIDDER_CODE, params: { placementId: '10433394', @@ -35,6 +36,7 @@ const bidReq = [{ auctionId: '9ad1fa8d-2297-4660-a018-b39945054746' }, { + adUnitCode: 'div-gpt-ad-1460505748561-0', bidder: BIDDER_CODE, params: { publisherId: 12345 @@ -54,6 +56,7 @@ const bidReqUserIds = [{ bidId: '263be71e91dd9d', auctionId: '9ad1fa8d-2297-4660-a018-b39945054746', userId: { + idl_env: '1111', tdid: '123456', digitrustid: {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}} } @@ -145,16 +148,43 @@ const bidResArray = [ } ]; -describe('Undertone Adapter', function () { - describe('request', function () { - it('should validate bid request', function () { +let element; +let sandbox; + +let elementParent = { + offsetLeft: 100, + offsetTop: 100, + offsetHeight: 100, + getAttribute: function() {} +}; + +describe('Undertone Adapter', () => { + describe('request', () => { + it('should validate bid request', () => { expect(spec.isBidRequestValid(validBidReq)).to.equal(true); }); - it('should not validate incorrect bid request', function () { + it('should not validate incorrect bid request', () => { expect(spec.isBidRequestValid(invalidBidReq)).to.equal(undefined); }); }); describe('build request', function () { + beforeEach(function() { + element = { + id: 'div-gpt-ad-1460505748561-0', + offsetLeft: 100, + offsetTop: 100, + offsetWidth: 300, + offsetHeight: 250 + }; + + sandbox = sinon.sandbox.create(); + sandbox.stub(document, 'getElementById').withArgs('div-gpt-ad-1460505748561-0').returns(element); + }); + + afterEach(function() { + sandbox.restore(); + }); + it('should send request to correct url via POST not in GDPR or CCPA', function () { const request = spec.buildRequests(bidReq, bidderReq); const domainStart = bidderReq.refererInfo.referer.indexOf('//'); @@ -202,6 +232,7 @@ describe('Undertone Adapter', function () { expect(bid1.sizes.length).to.equal(2); expect(bid1.placementId).to.equal('10433394'); expect(bid1.publisherId).to.equal(12345); + expect(bid1.coordinates).to.be.an('array'); expect(bid1.params).to.be.an('object'); const bid2 = JSON.parse(request.data)['x-ut-hb-params'][1]; expect(bid2.bidRequestId).to.equal('453cf42d72bb3c'); @@ -216,17 +247,41 @@ describe('Undertone Adapter', function () { expect(bidCommons).to.be.an('object'); expect(bidCommons.uids).to.be.an('object'); expect(bidCommons.uids.tdid).to.equal('123456'); + expect(bidCommons.uids.idl_env).to.equal('1111'); expect(bidCommons.uids.digitrustid.data.id).to.equal('DTID'); }); + it('should send page sizes sizes correctly', function () { + const request = spec.buildRequests(bidReqUserIds, bidderReq); + const bidCommons = JSON.parse(request.data)['commons']; + expect(bidCommons).to.be.an('object'); + expect(bidCommons.pageSize).to.be.an('array'); + expect(bidCommons.pageSize[0]).to.equal(window.innerWidth); + expect(bidCommons.pageSize[1]).to.equal(window.innerHeight); + }); + it('should send banner coordinates', function() { + const request = spec.buildRequests(bidReq, bidderReq); + const bid1 = JSON.parse(request.data)['x-ut-hb-params'][0]; + expect(bid1.coordinates).to.be.an('array'); + expect(bid1.coordinates[0]).to.equal(100); + expect(bid1.coordinates[1]).to.equal(100); + }); + it('should send banner coordinates plus parent', function() { + element.offsetParent = elementParent; + const request = spec.buildRequests(bidReq, bidderReq); + const bid1 = JSON.parse(request.data)['x-ut-hb-params'][0]; + expect(bid1.coordinates).to.be.an('array'); + expect(bid1.coordinates[0]).to.equal(200); + expect(bid1.coordinates[1]).to.equal(200); + }); }); - describe('interpretResponse', function () { - it('should build bid array', function () { + describe('interpretResponse', () => { + it('should build bid array', () => { let result = spec.interpretResponse({body: bidResponse}); expect(result.length).to.equal(1); }); - it('should have all relevant fields', function () { + it('should have all relevant fields', () => { const result = spec.interpretResponse({body: bidResponse}); const bid = result[0]; @@ -240,12 +295,12 @@ describe('Undertone Adapter', function () { expect(bid.ttl).to.equal(360); }); - it('should return empty array when response is incorrect', function () { + it('should return empty array when response is incorrect', () => { expect(spec.interpretResponse({body: {}}).length).to.equal(0); expect(spec.interpretResponse({body: []}).length).to.equal(0); }); - it('should only use valid bid responses', function () { + it('should only use valid bid responses', () => { expect(spec.interpretResponse({ body: bidResArray }).length).to.equal(1); }); });