diff --git a/modules/rubiconAnalyticsAdapter.js b/modules/rubiconAnalyticsAdapter.js index f216cbd6235..f1ba86de30f 100644 --- a/modules/rubiconAnalyticsAdapter.js +++ b/modules/rubiconAnalyticsAdapter.js @@ -60,7 +60,8 @@ const cache = { const BID_REJECTED_IPF = 'rejected-ipf'; export let rubiConf = { - pvid: utils.generateUUID().slice(0, 8) + pvid: utils.generateUUID().slice(0, 8), + analyticsEventDelay: 0 }; // we are saving these as global to this module so that if a pub accidentally overwrites the entire // rubicon object, then we do not lose other data @@ -487,7 +488,11 @@ function subscribeToGamSlots() { if (rubiConf.waitForGamSlots && !cache.auctions[auctionId].sent && Object.keys(cache.auctions[auctionId].gamHasRendered).every(adUnitCode => cache.auctions[auctionId].gamHasRendered[adUnitCode])) { clearTimeout(cache.timeouts[auctionId]); delete cache.timeouts[auctionId]; - sendMessage.call(rubiconAdapter, auctionId); + if (rubiConf.analyticsEventDelay > 0) { + setTimeout(() => sendMessage.call(rubiconAdapter, auctionId), rubiConf.analyticsEventDelay) + } else { + sendMessage.call(rubiconAdapter, auctionId) + } } }); }); @@ -568,9 +573,9 @@ let rubiconAdapter = Object.assign({}, baseAdapter, { cache.gpt.registered = true; } else if (!cache.gpt.registered) { cache.gpt.registered = true; - let googletag = window.googletag || {}; - googletag.cmd = googletag.cmd || []; - googletag.cmd.push(function() { + window.googletag = window.googletag || {}; + window.googletag.cmd = window.googletag.cmd || []; + window.googletag.cmd.push(function() { subscribeToGamSlots(); }); } diff --git a/test/spec/modules/rubiconAnalyticsAdapter_spec.js b/test/spec/modules/rubiconAnalyticsAdapter_spec.js index 71e5446ed06..505a2885404 100644 --- a/test/spec/modules/rubiconAnalyticsAdapter_spec.js +++ b/test/spec/modules/rubiconAnalyticsAdapter_spec.js @@ -636,6 +636,7 @@ describe('rubicon analytics adapter', function () { } }); expect(rubiConf).to.deep.equal({ + analyticsEventDelay: 0, pvid: '12345678', wrapperName: '1001_general', int_type: 'dmpbjs', @@ -654,6 +655,7 @@ describe('rubicon analytics adapter', function () { } }); expect(rubiConf).to.deep.equal({ + analyticsEventDelay: 0, pvid: '12345678', wrapperName: '1001_general', int_type: 'dmpbjs', @@ -674,6 +676,7 @@ describe('rubicon analytics adapter', function () { } }); expect(rubiConf).to.deep.equal({ + analyticsEventDelay: 0, pvid: '12345678', wrapperName: '1001_general', int_type: 'dmpbjs', @@ -1500,7 +1503,7 @@ describe('rubicon analytics adapter', function () { it('should send request when waitForGamSlots is present but no bidWons are sent', function () { config.setConfig({ rubicon: { - waitForGamSlots: true + waitForGamSlots: true, } }); events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); @@ -1511,7 +1514,7 @@ describe('rubicon analytics adapter', function () { events.emit(AUCTION_END, MOCK.AUCTION_END); events.emit(SET_TARGETING, MOCK.SET_TARGETING); - // should not send if just slotRenderEnded is emmitted for both + // should send if just slotRenderEnded is emmitted for both mockGpt.emitEvent(gptSlotRenderEnded0.eventName, gptSlotRenderEnded0.params); mockGpt.emitEvent(gptSlotRenderEnded1.eventName, gptSlotRenderEnded1.params); @@ -1536,6 +1539,51 @@ describe('rubicon analytics adapter', function () { }; expect(message).to.deep.equal(expectedMessage); }); + + it('should delay the event call depending on analyticsEventDelay config', function () { + config.setConfig({ + rubicon: { + waitForGamSlots: true, + analyticsEventDelay: 2000 + } + }); + events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); + events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); + events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); + events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]); + events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); + events.emit(AUCTION_END, MOCK.AUCTION_END); + events.emit(SET_TARGETING, MOCK.SET_TARGETING); + + // should send if just slotRenderEnded is emmitted for both + mockGpt.emitEvent(gptSlotRenderEnded0.eventName, gptSlotRenderEnded0.params); + mockGpt.emitEvent(gptSlotRenderEnded1.eventName, gptSlotRenderEnded1.params); + + // Should not be sent until delay + expect(server.requests.length).to.equal(0); + + // tick the clock and it should fire + clock.tick(2000); + + expect(server.requests.length).to.equal(1); + let request = server.requests[0]; + let message = JSON.parse(request.requestBody); + validate(message); + let expectedGam0 = { + advertiserId: 1111, + creativeId: 2222, + lineItemId: 3333, + adSlot: '/19968336/header-bid-tag-0' + }; + let expectedGam1 = { + advertiserId: 4444, + creativeId: 5555, + lineItemId: 6666, + adSlot: '/19968336/header-bid-tag1' + }; + expect(expectedGam0).to.deep.equal(message.auctions[0].adUnits[0].gam); + expect(expectedGam1).to.deep.equal(message.auctions[0].adUnits[1].gam); + }); }); it('should correctly overwrite bidId if seatBidId is on the bidResponse', function () {