UNPKG

mk9-prebid

Version:

Header Bidding Management Library

222 lines (198 loc) 6.67 kB
import { assert } from 'chai'; import { trackInstreamDeliveredImpressions } from 'modules/instreamTracking.js'; import { config } from 'src/config.js'; import events from 'src/events.js'; import * as utils from 'src/utils.js'; import * as sinon from 'sinon'; import { INSTREAM, OUTSTREAM } from 'src/video.js'; const BIDDER_CODE = 'sampleBidder'; const VIDEO_CACHE_KEY = '4cf395af-8fee-4960-af0e-88d44e399f14'; let sandbox; function enableInstreamTracking(regex) { let configStub = sandbox.stub(config, 'getConfig'); configStub.withArgs('instreamTracking').returns(Object.assign( { enabled: true, maxWindow: 10, pollingFreq: 0 }, regex && {urlPattern: regex}, )); } function mockPerformanceApi({adServerCallSent, videoPresent}) { let performanceStub = sandbox.stub(window.performance, 'getEntriesByType'); let entries = [{ name: 'https://domain.com/img.png', initiatorType: 'img' }, { name: 'https://domain.com/script.js', initiatorType: 'script' }, { name: 'https://domain.com/xhr', initiatorType: 'xmlhttprequest' }, { name: 'https://domain.com/fetch', initiatorType: 'fetch' }]; if (adServerCallSent || videoPresent) { entries.push({ name: 'https://adserver.com/ads?custom_params=hb_uuid%3D' + VIDEO_CACHE_KEY + '%26pos%3D' + VIDEO_CACHE_KEY, initiatorType: 'xmlhttprequest' }); } if (videoPresent) { entries.push({ name: 'https://prebid-vast-cache.com/cache?key=' + VIDEO_CACHE_KEY, initiatorType: 'xmlhttprequest' }); } performanceStub.withArgs('resource').returns(entries); } function mockBidResponse(adUnit, requestId) { const bid = { 'adUnitCod': adUnit.code, 'bidderCode': adUnit.bids[0].bidder, 'width': adUnit.sizes[0][0], 'height': adUnit.sizes[0][1], 'statusMessage': 'Bid available', 'adId': 'id', 'requestId': requestId, 'source': 'client', 'no_bid': false, 'cpm': '1.1495', 'ttl': 180, 'creativeId': 'id', 'netRevenue': true, 'currency': 'USD', } if (adUnit.mediaTypes.video) { bid.videoCacheKey = VIDEO_CACHE_KEY; } return bid } function mockBidRequest(adUnit, bidResponse) { return { 'bidderCode': bidResponse.bidderCode, 'auctionId': '20882439e3238c', 'bidderRequestId': 'bidderRequestId', 'bids': [ { 'adUnitCode': adUnit.code, 'mediaTypes': adUnit.mediaTypes, 'bidder': bidResponse.bidderCode, 'bidId': bidResponse.requestId, 'sizes': adUnit.sizes, 'params': adUnit.bids[0].params, 'bidderRequestId': 'bidderRequestId', 'auctionId': '20882439e3238c', } ], 'auctionStart': 1505250713622, 'timeout': 3000 }; } function getMockInput(mediaType) { const bannerAdUnit = { code: 'banner', mediaTypes: {banner: {sizes: [[300, 250]]}}, sizes: [[300, 250]], bids: [{bidder: BIDDER_CODE, params: {placementId: 'id'}}] }; const outStreamAdUnit = { code: 'video-' + OUTSTREAM, mediaTypes: {video: {playerSize: [640, 480], context: OUTSTREAM}}, sizes: [[640, 480]], bids: [{bidder: BIDDER_CODE, params: {placementId: 'id'}}] }; const inStreamAdUnit = { code: 'video-' + INSTREAM, mediaTypes: {video: {playerSize: [640, 480], context: INSTREAM}}, sizes: [[640, 480]], bids: [{bidder: BIDDER_CODE, params: {placementId: 'id'}}] }; let adUnit; switch (mediaType) { default: case 'banner': adUnit = bannerAdUnit; break; case OUTSTREAM: adUnit = outStreamAdUnit; break; case INSTREAM: adUnit = inStreamAdUnit; break; } const bidResponse = mockBidResponse(adUnit, utils.getUniqueIdentifierStr()); const bidderRequest = mockBidRequest(adUnit, bidResponse); return { adUnits: [adUnit], bidsReceived: [bidResponse], bidderRequests: [bidderRequest], }; } describe('Instream Tracking', function () { beforeEach(function () { sandbox = sinon.sandbox.create(); }); afterEach(function () { sandbox.restore(); }); describe('gaurd checks', function () { it('skip if tracking not enable', function () { sandbox.stub(config, 'getConfig').withArgs('instreamTracking').returns(undefined); assert.isNotOk(trackInstreamDeliveredImpressions({ adUnits: [], bidsReceived: [], bidderRequests: [] }), 'should not start tracking when tracking is disabled'); }); it('run only if instream bids are present', function () { enableInstreamTracking(); assert.isNotOk(trackInstreamDeliveredImpressions({adUnits: [], bidsReceived: [], bidderRequests: []})); }); it('checks for instream bids', function (done) { enableInstreamTracking(); assert.isNotOk(trackInstreamDeliveredImpressions(getMockInput('banner')), 'should not start tracking when banner bids are present') assert.isNotOk(trackInstreamDeliveredImpressions(getMockInput(OUTSTREAM)), 'should not start tracking when outstream bids are present') mockPerformanceApi({}); assert.isOk(trackInstreamDeliveredImpressions(getMockInput(INSTREAM)), 'should start tracking when instream bids are present') setTimeout(done, 10); }); }); describe('instream bids check', function () { let spyEventsOn; beforeEach(function () { spyEventsOn = sandbox.spy(events, 'emit'); }); it('BID WON event is not emitted when no video cache key entries are present', function (done) { enableInstreamTracking(); trackInstreamDeliveredImpressions(getMockInput(INSTREAM)); mockPerformanceApi({}); setTimeout(function () { assert.isNotOk(spyEventsOn.calledWith('bidWon')) done() }, 10); }); it('BID WON event is not emitted when ad server call is sent', function (done) { enableInstreamTracking(); mockPerformanceApi({adServerCallSent: true}); setTimeout(function () { assert.isNotOk(spyEventsOn.calledWith('bidWon')) done() }, 10); }); it('BID WON event is emitted when video cache key is present', function (done) { enableInstreamTracking(/cache/); const bidWonSpy = sandbox.spy(); events.on('bidWon', bidWonSpy); mockPerformanceApi({adServerCallSent: true, videoPresent: true}); trackInstreamDeliveredImpressions(getMockInput(INSTREAM)); setTimeout(function () { assert.isOk(spyEventsOn.calledWith('bidWon')) assert(bidWonSpy.args[0][0].videoCacheKey, VIDEO_CACHE_KEY, 'Video cache key in bid won should be equal to video cache call'); done() }, 10); }); }); });