From d7d1738ec0116ddf5d4bbd877b64312187f4b981 Mon Sep 17 00:00:00 2001 From: Jaimin Panchal Date: Fri, 10 Nov 2017 16:27:20 -0500 Subject: [PATCH] Unit test fixes for IE 10 and other old browsers (#1810) * Added fix for location.origin * Fixed test case failing in IE and Safari browsers * Added utils.getOrigin method * Updated renderer to use hooks --- modules/nanointeractiveBidAdapter.js | 2 +- src/utils.js | 12 ++ test/spec/auctionmanager_spec.js | 300 ++++++++++++++++----------- test/spec/renderer_spec.js | 38 ++-- test/spec/unit/pbjs_api_spec.js | 36 ---- 5 files changed, 211 insertions(+), 177 deletions(-) diff --git a/modules/nanointeractiveBidAdapter.js b/modules/nanointeractiveBidAdapter.js index 9781e36edb6..c4cce6646d3 100644 --- a/modules/nanointeractiveBidAdapter.js +++ b/modules/nanointeractiveBidAdapter.js @@ -55,7 +55,7 @@ function createSingleBidRequest(bid) { [NQ]: [createNqParam(bid), createCategoryParam(bid)], sizes: bid.sizes.map(value => value[0] + 'x' + value[1]), bidId: bid.bidId, - cors: location.origin + cors: utils.getOrigin() }; } diff --git a/src/utils.js b/src/utils.js index 60e6168f803..9c29e233380 100644 --- a/src/utils.js +++ b/src/utils.js @@ -771,3 +771,15 @@ export function getBidderRequest(bidRequests, bidder, adUnitCode) { .filter(bid => bid.bidder === bidder && bid.adUnitCode === adUnitCode).length > 0; }) || { start: null, requestId: null }; } + +/** + * Returns the origin + */ +export function getOrigin() { + // IE10 does not have this propery. https://gist.github.com/hbogs/7908703 + if (!window.location.origin) { + return window.location.protocol + '//' + window.location.hostname + (window.location.port ? ':' + window.location.port : ''); + } else { + return window.location.origin; + } +} diff --git a/test/spec/auctionmanager_spec.js b/test/spec/auctionmanager_spec.js index 2f6d9fa5daa..a3cfa88db82 100644 --- a/test/spec/auctionmanager_spec.js +++ b/test/spec/auctionmanager_spec.js @@ -15,6 +15,7 @@ var utils = require('../../src/utils'); var bidfactory = require('../../src/bidfactory'); var fixtures = require('../fixtures/fixtures'); var adaptermanager = require('src/adaptermanager'); +var events = require('src/events'); function timestamp() { return new Date().getTime(); @@ -468,140 +469,193 @@ describe('auctionmanager.js', function () { adaptermanager.makeBidRequests.restore(); }); - beforeEach(() => { - adUnits = [{ - code: 'adUnit-code', - bids: [ - {bidder: BIDDER_CODE, params: {placementId: 'id'}}, - ] - }]; - adUnitCodes = ['adUnit-code']; - auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: function() {}, cbTimeout: 3000}); - createAuctionStub = sinon.stub(auctionModule, 'newAuction'); - createAuctionStub.returns(auction); - - spec = { - code: BIDDER_CODE, - isBidRequestValid: sinon.stub(), - buildRequests: sinon.stub(), - interpretResponse: sinon.stub(), - getUserSyncs: sinon.stub() - }; - }); + describe('when auction timeout is 3000', () => { + beforeEach(() => { + adUnits = [{ + code: 'adUnit-code', + bids: [ + {bidder: BIDDER_CODE, params: {placementId: 'id'}}, + ] + }]; + adUnitCodes = ['adUnit-code']; + auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: function() {}, cbTimeout: 3000}); + createAuctionStub = sinon.stub(auctionModule, 'newAuction'); + createAuctionStub.returns(auction); + + spec = { + code: BIDDER_CODE, + isBidRequestValid: sinon.stub(), + buildRequests: sinon.stub(), + interpretResponse: sinon.stub(), + getUserSyncs: sinon.stub() + }; + }); - afterEach(() => { - auctionModule.newAuction.restore(); - }); + afterEach(() => { + auctionModule.newAuction.restore(); + }); - it('should return proper price bucket increments for dense mode when cpm is in range 0-3', () => { - bids[0].cpm = '1.99'; - registerBidder(spec); - spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); - spec.isBidRequestValid.returns(true); - spec.interpretResponse.returns(bids); - auction.callBids(); - let registeredBid = auction.getBidsReceived().pop(); - assert.equal(registeredBid.pbDg, '1.99', '0 - 3 hits at to 1 cent increment'); - }); + it('should return proper price bucket increments for dense mode when cpm is in range 0-3', () => { + bids[0].cpm = '1.99'; + registerBidder(spec); + spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); + spec.isBidRequestValid.returns(true); + spec.interpretResponse.returns(bids); + auction.callBids(); + let registeredBid = auction.getBidsReceived().pop(); + assert.equal(registeredBid.pbDg, '1.99', '0 - 3 hits at to 1 cent increment'); + }); - it('should return proper price bucket increments for dense mode when cpm is in range 3-8', () => { - bids[0].cpm = '4.39'; - registerBidder(spec); - spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); - spec.isBidRequestValid.returns(true); - spec.interpretResponse.returns(bids); - auction.callBids(); - let registeredBid = auction.getBidsReceived().pop(); - assert.equal(registeredBid.pbDg, '4.35', '3 - 8 hits at 5 cent increment'); - }); + it('should return proper price bucket increments for dense mode when cpm is in range 3-8', () => { + bids[0].cpm = '4.39'; + registerBidder(spec); + spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); + spec.isBidRequestValid.returns(true); + spec.interpretResponse.returns(bids); + auction.callBids(); + let registeredBid = auction.getBidsReceived().pop(); + assert.equal(registeredBid.pbDg, '4.35', '3 - 8 hits at 5 cent increment'); + }); - it('should return proper price bucket increments for dense mode when cpm is in range 8-20', () => { - bids[0].cpm = '19.99'; - registerBidder(spec); - spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); - spec.isBidRequestValid.returns(true); - spec.interpretResponse.returns(bids); - auction.callBids(); - let registeredBid = auction.getBidsReceived().pop(); - assert.equal(registeredBid.pbDg, '19.50', '8 - 20 hits at 50 cent increment'); - }); + it('should return proper price bucket increments for dense mode when cpm is in range 8-20', () => { + bids[0].cpm = '19.99'; + registerBidder(spec); + spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); + spec.isBidRequestValid.returns(true); + spec.interpretResponse.returns(bids); + auction.callBids(); + let registeredBid = auction.getBidsReceived().pop(); + assert.equal(registeredBid.pbDg, '19.50', '8 - 20 hits at 50 cent increment'); + }); - it('should return proper price bucket increments for dense mode when cpm is 20+', () => { - bids[0].cpm = '73.07'; - registerBidder(spec); - spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); - spec.isBidRequestValid.returns(true); - spec.interpretResponse.returns(bids); - auction.callBids(); - let registeredBid = auction.getBidsReceived().pop(); - assert.equal(registeredBid.pbDg, '20.00', '20+ caps at 20.00'); - }); + it('should return proper price bucket increments for dense mode when cpm is 20+', () => { + bids[0].cpm = '73.07'; + registerBidder(spec); + spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); + spec.isBidRequestValid.returns(true); + spec.interpretResponse.returns(bids); + auction.callBids(); + let registeredBid = auction.getBidsReceived().pop(); + assert.equal(registeredBid.pbDg, '20.00', '20+ caps at 20.00'); + }); - it('should place dealIds in adserver targeting', () => { - bids[0].dealId = 'test deal'; - registerBidder(spec); - spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); - spec.isBidRequestValid.returns(true); - spec.interpretResponse.returns(bids); - auction.callBids(); - let registeredBid = auction.getBidsReceived().pop(); - assert.equal(registeredBid.adserverTargeting[`hb_deal`], 'test deal', 'dealId placed in adserverTargeting'); - }); + it('should place dealIds in adserver targeting', () => { + bids[0].dealId = 'test deal'; + registerBidder(spec); + spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); + spec.isBidRequestValid.returns(true); + spec.interpretResponse.returns(bids); + auction.callBids(); + let registeredBid = auction.getBidsReceived().pop(); + assert.equal(registeredBid.adserverTargeting[`hb_deal`], 'test deal', 'dealId placed in adserverTargeting'); + }); - it('should pass through default adserverTargeting sent from adapter', () => { - bids[0].adserverTargeting = {}; - bids[0].adserverTargeting.extra = 'stuff'; - registerBidder(spec); - spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); - spec.isBidRequestValid.returns(true); - spec.interpretResponse.returns(bids); - auction.callBids(); - let registeredBid = auction.getBidsReceived().pop(); - assert.equal(registeredBid.adserverTargeting.hb_bidder, 'sampleBidder'); - assert.equal(registeredBid.adserverTargeting.extra, 'stuff'); - }); + it('should pass through default adserverTargeting sent from adapter', () => { + bids[0].adserverTargeting = {}; + bids[0].adserverTargeting.extra = 'stuff'; + registerBidder(spec); + spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); + spec.isBidRequestValid.returns(true); + spec.interpretResponse.returns(bids); + auction.callBids(); + let registeredBid = auction.getBidsReceived().pop(); + assert.equal(registeredBid.adserverTargeting.hb_bidder, 'sampleBidder'); + assert.equal(registeredBid.adserverTargeting.extra, 'stuff'); + }); - it('installs publisher-defined renderers on bids', () => { - let bidRequests = [{ - 'bidderCode': BIDDER_CODE, - 'auctionId': '20882439e3238c', - 'bidderRequestId': '331f3cf3f1d9c8', - 'bids': [ - { - 'bidder': BIDDER_CODE, - 'params': { - 'placementId': 'id' - }, - 'adUnitCode': 'adUnit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '4d0a6829338a07', - 'bidderRequestId': '331f3cf3f1d9c8', - 'auctionId': '20882439e3238c', - 'renderer': { - url: 'renderer.js', - render: (bid) => bid + it('installs publisher-defined renderers on bids', () => { + let bidRequests = [{ + 'bidderCode': BIDDER_CODE, + 'auctionId': '20882439e3238c', + 'bidderRequestId': '331f3cf3f1d9c8', + 'bids': [ + { + 'bidder': BIDDER_CODE, + 'params': { + 'placementId': 'id' + }, + 'adUnitCode': 'adUnit-code', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '4d0a6829338a07', + 'bidderRequestId': '331f3cf3f1d9c8', + 'auctionId': '20882439e3238c', + 'renderer': { + url: 'renderer.js', + render: (bid) => bid + } } + ], + 'auctionStart': 1505250713622, + 'timeout': 3000 + }]; + + makeRequestsStub.returns(bidRequests); + let bids1 = Object.assign({}, + bids[0], + { + bidderCode: BIDDER_CODE, + mediaType: 'video-outstream', } - ], - 'auctionStart': 1505250713622, - 'timeout': 3000 - }]; + ); + registerBidder(spec); + spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); + spec.isBidRequestValid.returns(true); + spec.interpretResponse.returns(bids1); + auction.callBids(); + const addedBid = auction.getBidsReceived().pop(); + assert.equal(addedBid.renderer.url, 'renderer.js'); + }); + }); - makeRequestsStub.returns(bidRequests); - let bids1 = Object.assign({}, - bids[0], - { - bidderCode: BIDDER_CODE, - mediaType: 'video-outstream', - } - ); - registerBidder(spec); - spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); - spec.isBidRequestValid.returns(true); - spec.interpretResponse.returns(bids1); - auction.callBids(); - const addedBid = auction.getBidsReceived().pop(); - assert.equal(addedBid.renderer.url, 'renderer.js'); + describe('with auction timeout 20', () => { + let auction; + let adUnits; + let adUnitCodes; + let createAuctionStub; + let spec; + let getBidderRequestStub; + let eventsEmitSpy; + + beforeEach(() => { + adUnits = [{ + code: 'adUnit-code', + bids: [ + {bidder: BIDDER_CODE, params: {placementId: 'id'}}, + ] + }]; + adUnitCodes = ['adUnit-code']; + auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: function() {}, cbTimeout: 20}); + createAuctionStub = sinon.stub(auctionModule, 'newAuction'); + createAuctionStub.returns(auction); + getBidderRequestStub = sinon.stub(utils, 'getBidderRequest'); + + let newBidRequest = Object.assign({}, bidRequests[0], {'start': 1000}); + getBidderRequestStub.returns(newBidRequest); + + spec = { + code: BIDDER_CODE, + isBidRequestValid: sinon.stub(), + buildRequests: sinon.stub(), + interpretResponse: sinon.stub(), + getUserSyncs: sinon.stub() + }; + eventsEmitSpy = sinon.spy(events, 'emit'); + }); + + afterEach(() => { + auctionModule.newAuction.restore(); + utils.getBidderRequest.restore(); + events.emit.restore(); + }); + + it('should emit BID_TIMEOUT for timed out bids', () => { + registerBidder(spec); + spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); + spec.isBidRequestValid.returns(true); + spec.interpretResponse.returns(bids); + auction.callBids(); + assert.ok(eventsEmitSpy.calledWith(CONSTANTS.EVENTS.BID_TIMEOUT), 'emitted events BID_TIMEOUT'); + }); }); }); diff --git a/test/spec/renderer_spec.js b/test/spec/renderer_spec.js index 282c4841ac0..4761a914bb8 100644 --- a/test/spec/renderer_spec.js +++ b/test/spec/renderer_spec.js @@ -2,19 +2,26 @@ import { expect } from 'chai'; import { Renderer } from 'src/Renderer'; describe('Renderer: A renderer installed on a bid response', () => { - const testRenderer1 = Renderer.install({ - url: 'https://httpbin.org/post', - config: { test: 'config1' }, - id: 1 - }); - const testRenderer2 = Renderer.install({ - url: 'https://httpbin.org/post', - config: { test: 'config2' }, - id: 2 - }); + let testRenderer1; + let testRenderer2; + let spyRenderFn; + let spyEventHandler; + + beforeEach(() => { + testRenderer1 = Renderer.install({ + url: 'https://httpbin.org/post', + config: { test: 'config1' }, + id: 1 + }); + testRenderer2 = Renderer.install({ + url: 'https://httpbin.org/post', + config: { test: 'config2' }, + id: 2 + }); - const spyRenderFn = sinon.spy(); - const spyEventHandler = sinon.spy(); + spyRenderFn = sinon.spy(); + spyEventHandler = sinon.spy(); + }); it('is an instance of Renderer', () => { expect(testRenderer1 instanceof Renderer).to.equal(true); @@ -34,12 +41,11 @@ describe('Renderer: A renderer installed on a bid response', () => { it('sets a render function with setRender method', () => { testRenderer1.setRender(spyRenderFn); expect(typeof testRenderer1.render).to.equal('function'); - testRenderer1.render(); expect(spyRenderFn.called).to.equal(true); }); - it('sets event handlers with setEventHandlers method', () => { + it('sets event handlers with setEventHandlers method and handles events with installed handlers', () => { testRenderer1.setEventHandlers({ testEvent: spyEventHandler }); @@ -47,16 +53,13 @@ describe('Renderer: A renderer installed on a bid response', () => { expect(testRenderer1.handlers).to.deep.equal({ testEvent: spyEventHandler }); - }); - it('handles events with installed handlers', () => { testRenderer1.handleVideoEvent({ id: 1, eventName: 'testEvent' }); expect(spyEventHandler.called).to.equal(true); }); it('pushes commands to queue if renderer is not loaded', () => { testRenderer1.push(spyRenderFn); - expect(testRenderer1.cmd.length).to.equal(1); // clear queue for next tests @@ -70,6 +73,7 @@ describe('Renderer: A renderer installed on a bid response', () => { testRenderer1.push(func); expect(testRenderer1.cmd.length).to.equal(0); + sinon.assert.calledOnce(func); }); diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js index fc82cf4a704..613074e59f9 100644 --- a/test/spec/unit/pbjs_api_spec.js +++ b/test/spec/unit/pbjs_api_spec.js @@ -1289,42 +1289,6 @@ describe('Unit: Prebid Module', function () { }); }); - describe('sendTimeoutEvent', () => { - let auctionManagerStub; - beforeEach(() => { - auctionManagerStub = sinon.stub(auctionManager, 'createAuction', function() { - return auction; - }); - }); - - afterEach(() => { - auctionManager.createAuction.restore(); - }); - - it('should emit BID_TIMEOUT for timed out bids', () => { - const eventsEmitSpy = sinon.spy(events, 'emit'); - - var requestObj = { - bidsBackHandler: function bidsBackHandlerCallback() {}, - timeout: 20 - }; - var adUnits = [{ - code: 'code', - bids: [{ - bidder: 'appnexus', - params: { placementId: '123' } - }] - }]; - $$PREBID_GLOBAL$$.adUnits = adUnits; - $$PREBID_GLOBAL$$.requestBids(requestObj); - - setTimeout(function () { - assert.ok(eventsEmitSpy.calledWith(CONSTANTS.EVENTS.BID_TIMEOUT), 'emitted events BID_TIMEOUT'); - events.emit.restore(); - }, 100); - }); - }); - describe('aliasBidder', () => { it('should call adaptermanager.aliasBidder', () => { const aliasBidAdapterSpy = sinon.spy(adaptermanager, 'aliasBidAdapter');