UNPKG

mk9-prebid

Version:

Header Bidding Management Library

536 lines (500 loc) 16.3 kB
import { assert, expect } from 'chai'; import { spec } from 'modules/sspBCBidAdapter.js'; import * as utils from 'src/utils.js'; const BIDDER_CODE = 'sspBC'; const BIDDER_URL = 'https://ssp.wp.pl/bidder/'; const SYNC_URL = 'https://ssp.wp.pl/bidder/usersync'; describe('SSPBC adapter', function () { function prepareTestData() { const bidderRequestId = '1041bb47b0fafa'; const auctionId = '8eda6d06-3d7c-4a94-9b35-74e42fbb3089'; const transactionId = '50259989-b5c0-4edf-8f47-b1ef5fbedf39'; const gdprConsent = { consentString: 'BOtq-3dOtq-30BIABCPLC4-AAAAthr_7__7-_9_-_f__9uj3Or_v_f__30ccL59v_h_7v-_7fi_20nV4u_1vft9yfk1-5ctDztp505iakivHmqNeb9v_mz1_5pRP78k89r7337Ew_v8_v-b7JCON_Ig', gdprApplies: true, } const bids = [{ adUnitCode: 'test_wideboard', bidder: BIDDER_CODE, mediaTypes: { banner: { sizes: [ [728, 90], [750, 100], [750, 200] ] } }, sizes: [ [728, 90], [750, 100], [750, 200] ], params: { id: '003', siteId: '8816', }, auctionId, bidderRequestId, bidId: auctionId + '1', transactionId, ortb2Imp: { ext: { data: { pbadslot: 'test_wideboard' } } } }, { adUnitCode: 'test_rectangle', bidder: BIDDER_CODE, mediaTypes: { banner: { sizes: [ [300, 250] ] } }, sizes: [ [300, 250] ], params: { id: '005', siteId: '8816', }, auctionId, bidderRequestId, bidId: auctionId + '2', transactionId, }, { adUnitCode: 'test_rectangle_2', bidder: BIDDER_CODE, mediaTypes: { banner: { sizes: [ [300, 250] ] } }, sizes: [ [300, 250] ], params: { id: '011', siteId: '8816', }, auctionId, bidderRequestId, bidId: auctionId + '3', transactionId, } ]; const bid_OneCode = { adUnitCode: 'test_wideboard', bidder: BIDDER_CODE, mediaTypes: { banner: { sizes: [ [728, 90], [750, 100], [750, 200] ] } }, sizes: [ [728, 90], [750, 100], [750, 200] ], auctionId, bidderRequestId, bidId: auctionId + '1', transactionId, }; const bids_timeouted = [{ adUnitCode: 'test_wideboard', bidder: BIDDER_CODE, params: [{ id: '003', siteId: '8816', }], auctionId, bidId: auctionId + '1', timeout: 100, }, { adUnitCode: 'test_rectangle', bidder: BIDDER_CODE, params: [{ id: '005', siteId: '8816', }], auctionId, bidId: auctionId + '2', timeout: 100, } ]; const bids_test = [{ adUnitCode: 'test_wideboard', bidder: BIDDER_CODE, mediaTypes: { banner: { sizes: [ [970, 300], [750, 300], [750, 200], [750, 100], [300, 250] ] } }, sizes: [ [970, 300], [750, 300], [750, 200], [750, 100], [300, 250] ], params: { id: '005', siteId: '235911', test: 1 }, auctionId, bidderRequestId, bidId: auctionId + '1', transactionId, }]; const bidRequest = { auctionId, bidderCode: BIDDER_CODE, bidderRequestId, bids, gdprConsent, refererInfo: { reachedTop: true, referer: 'https://test.site.pl/', stack: ['https://test.site.pl/'], } }; const bidRequestSingle = { auctionId, bidderCode: BIDDER_CODE, bidderRequestId, bids: [bids[0]], gdprConsent, refererInfo: { reachedTop: true, referer: 'https://test.site.pl/', stack: ['https://test.site.pl/'], } }; const bidRequestOneCode = { auctionId, bidderCode: BIDDER_CODE, bidderRequestId, bids: [bid_OneCode], gdprConsent, refererInfo: { reachedTop: true, referer: 'https://test.site.pl/', stack: ['https://test.site.pl/'], } }; const bidRequestTest = { auctionId, bidderCode: BIDDER_CODE, bidderRequestId, bids: bids_test, gdprConsent, refererInfo: { reachedTop: true, referer: 'https://test.site.pl/', stack: ['https://test.site.pl/'], } }; const bidRequestTestNoGDPR = { auctionId, bidderCode: BIDDER_CODE, bidderRequestId, bids: bids_test, refererInfo: { reachedTop: true, referer: 'https://test.site.pl/', stack: ['https://test.site.pl/'], } }; const serverResponse = { 'body': { 'id': auctionId, 'seatbid': [{ 'bid': [{ 'id': '3347324c-6889-46d2-a800-ae78a5214c06', 'impid': '003', 'siteid': '8816', 'slotid': '003', 'price': 1, 'adid': 'lxHWkB7OnZeso3QiN1N4', 'nurl': '', 'adm': 'AD CODE 1', 'adomain': ['adomain.pl'], 'cid': 'BZ4gAg21T5nNtxlUCDSW', 'crid': 'lxHWkB7OnZeso3QiN1N4', 'w': 728, 'h': 90 }], 'seat': 'dsp1', 'group': 0 }, { 'bid': [{ 'id': '2d766853-ea07-4529-8299-5f0ebadc546a', 'impid': '005', 'siteid': '8816', 'slotid': '005', 'price': 2, 'adm': 'AD CODE 2', 'cid': '57744', 'crid': '858252', 'w': 300, 'h': 250 }], 'seat': 'dsp2', 'group': 0 }, { 'bid': [{ 'id': '2d766853-ea07-4529-8299-5f0ebaddfaza', 'impid': '011', 'siteid': '8816', 'slotid': '011', 'price': 2, 'adm': 'AD CODE 3', 'cid': '57745', 'crid': '858253', 'w': 300, 'h': 250 }], 'seat': 'dsp3', 'group': 0 }], 'cur': 'PLN' } }; const serverResponseSingle = { 'body': { 'id': auctionId, 'seatbid': [{ 'bid': [{ 'id': '3347324c-6889-46d2-a800-ae78a5214c06', 'impid': '003', 'siteid': '8816', 'slotid': '003', 'price': 1, 'adid': 'lxHWkB7OnZeso3QiN1N4', 'nurl': '', 'adm': 'AD CODE 1', 'adomain': ['adomain.pl'], 'cid': 'BZ4gAg21T5nNtxlUCDSW', 'crid': 'lxHWkB7OnZeso3QiN1N4', 'w': 728, 'h': 90 }], 'seat': 'dsp1', 'group': 0 }], 'cur': 'PLN' } }; const serverResponseOneCode = { 'body': { 'id': auctionId, 'seatbid': [{ 'bid': [{ 'id': '3347324c-6889-46d2-a800-ae78a5214c06', 'impid': 'bidid-' + auctionId + '1', 'price': 1, 'adid': 'lxHWkB7OnZeso3QiN1N4', 'nurl': '', 'adm': 'AD CODE 1', 'adomain': ['adomain.pl'], 'cid': 'BZ4gAg21T5nNtxlUCDSW', 'crid': 'lxHWkB7OnZeso3QiN1N4', 'w': 728, 'h': 90, 'ext': { 'siteid': '8816', 'slotid': '003', }, }], 'seat': 'dsp1', 'group': 0 }], 'cur': 'PLN' } }; const emptyResponse = { 'body': { 'id': auctionId, } } return { bid_OneCode, bids, bids_test, bids_timeouted, bidRequest, bidRequestOneCode, bidRequestSingle, bidRequestTest, bidRequestTestNoGDPR, serverResponse, serverResponseOneCode, serverResponseSingle, emptyResponse }; }; describe('dependencies', function () { it('utils should contain required functions', function () { expect(utils.parseUrl).to.be.a('function'); expect(utils.deepAccess).to.be.a('function'); expect(utils.logWarn).to.be.a('function'); }); }); describe('isBidRequestValid', function () { const { bids } = prepareTestData(); let bid = bids[0]; it('should always return true whether bid has params (standard) or not (OneCode)', function () { assert(spec.isBidRequestValid(bid)); bid.params.id = undefined; assert(spec.isBidRequestValid(bid)); }); }); describe('buildRequests', function () { const { bids, bidRequest, bidRequestSingle } = prepareTestData(); const request = spec.buildRequests(bids, bidRequest); const requestSingle = spec.buildRequests([bids[0]], bidRequestSingle); const payload = request ? JSON.parse(request.data) : { site: false, imp: false }; const payloadSingle = request ? JSON.parse(requestSingle.data) : { site: false, imp: false }; const payloadExt0 = payload.imp ? payload.imp[0].ext : {}; const payloadExt1 = payload.imp ? payload.imp[1].ext : {}; const payloadExt2 = payload.imp ? payload.imp[2].ext : {}; it('should send bid request to endpoint via POST', function () { expect(request.url).to.contain(BIDDER_URL); expect(request.method).to.equal('POST'); }); it('should contain prebid and bidder versions', function () { expect(request.url).to.contain('bdver'); expect(request.url).to.contain('pbver=$prebid.version$'); }); it('should create one imp object per bid', function () { expect(payload.imp.length).to.equal(bids.length); expect(payloadSingle.imp.length).to.equal(1); }); it('should add first party data (pbslot)', function () { expect(payloadExt0.data).to.be.an('object').and.to.have.property('pbadslot'); }); it('should add maximum size of adunit, and how many times this size has been requested (pbsize)', function () { expect(payloadExt0.data).to.be.an('object').and.to.have.property('pbsize'); expect(payloadExt0.data.pbsize).to.equal('750x200_1'); expect(payloadExt1.data.pbsize).to.equal('300x250_1'); expect(payloadExt2.data.pbsize).to.equal('300x250_2'); }); it('should save bidder request data', function () { expect(request.bidderRequest).to.deep.equal(bidRequest); }); it('should send site Id from bidder params', function () { expect(payload.site.id).to.equal(bids[0].params.siteId); }); it('should send page url from refererInfo', function () { expect(payload.site.page).to.equal(bidRequest.refererInfo.referer); }); it('should send gdpr data', function () { expect(payload.regs).to.be.an('object').and.to.have.property('[ortb_extensions.gdpr]', 1); expect(payload.user).to.be.an('object').and.to.have.property('[ortb_extensions.consent]', bidRequest.gdprConsent.consentString); }); }); describe('interpretResponse', function () { const { bid_OneCode, bids, emptyResponse, serverResponse, serverResponseOneCode, serverResponseSingle, bidRequest, bidRequestOneCode, bidRequestSingle } = prepareTestData(); const request = spec.buildRequests(bids, bidRequest); const requestSingle = spec.buildRequests([bids[0]], bidRequestSingle); const requestOneCode = spec.buildRequests([bid_OneCode], bidRequestOneCode); it('should handle nobid responses', function () { let result = spec.interpretResponse(emptyResponse, request); expect(result.length).to.equal(0); }); it('should create bids from non-empty responses', function () { let result = spec.interpretResponse(serverResponse, request); let resultSingle = spec.interpretResponse(serverResponseSingle, requestSingle); expect(result.length).to.equal(bids.length); expect(resultSingle.length).to.equal(1); expect(resultSingle[0]).to.have.keys('ad', 'cpm', 'width', 'height', 'bidderCode', 'mediaType', 'meta', 'requestId', 'creativeId', 'currency', 'netRevenue', 'ttl'); }); it('should create bid from OneCode (parameter-less) request, if response contains siteId', function () { let resultOneCode = spec.interpretResponse(serverResponseOneCode, requestOneCode); expect(resultOneCode.length).to.equal(1); expect(resultOneCode[0]).to.have.keys('ad', 'cpm', 'width', 'height', 'bidderCode', 'mediaType', 'meta', 'requestId', 'creativeId', 'currency', 'netRevenue', 'ttl'); }); it('should not create bid from OneCode (parameter-less) request, if response does not contain siteId', function () { let resultOneCodeNoMatch = spec.interpretResponse(serverResponse, requestOneCode); expect(resultOneCodeNoMatch.length).to.equal(0); }); it('should handle a partial response', function () { let resultPartial = spec.interpretResponse(serverResponseSingle, request); expect(resultPartial.length).to.equal(1); }); it('banner ad code should contain required variables', function () { let resultSingle = spec.interpretResponse(serverResponseSingle, requestSingle); let adcode = resultSingle[0].ad; expect(adcode).to.be.a('string'); expect(adcode).to.contain('window.rekid'); expect(adcode).to.contain('window.mcad'); expect(adcode).to.contain('window.gdpr'); expect(adcode).to.contain('window.page'); }) }); describe('getUserSyncs', function () { let syncResultAll = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }); let syncResultImage = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }); let syncResultNone = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }); it('should provide correct url, if frame sync is allowed', function () { expect(syncResultAll).to.have.length(1); expect(syncResultAll[0].url).to.have.string(SYNC_URL); }); it('should send no syncs, if frame sync is not allowed', function () { expect(syncResultImage).to.be.undefined; expect(syncResultNone).to.be.undefined; }); }); describe('onBidWon', function () { it('should generate no notification if bid is undefined', function () { let notificationPayload = spec.onBidWon(); expect(notificationPayload).to.be.undefined; }); it('should generate notification with event name and request/adUnit data, if correct bid is provided. Should also contain site/slot data as arrays.', function () { const { bids } = prepareTestData(); let bid = bids[0]; let notificationPayload = spec.onBidWon(bid); expect(notificationPayload).to.have.property('event').that.equals('bidWon'); expect(notificationPayload).to.have.property('requestId').that.equals(bid.auctionId); expect(notificationPayload).to.have.property('adUnit').that.deep.equals([bid.adUnitCode]); expect(notificationPayload).to.have.property('siteId').that.is.an('array'); expect(notificationPayload).to.have.property('slotId').that.is.an('array'); }); }); describe('onTimeout', function () { it('should generate no notification if timeout data is undefined / has no bids', function () { let notificationPayloadUndefined = spec.onTimeout(); let notificationPayloadNoBids = spec.onTimeout([]); expect(notificationPayloadUndefined).to.be.undefined; expect(notificationPayloadNoBids).to.be.undefined; }); it('should generate single notification for any number of timeouted bids', function () { const { bids_timeouted } = prepareTestData(); let notificationPayload = spec.onTimeout(bids_timeouted); expect(notificationPayload).to.have.property('event').that.equals('timeout'); expect(notificationPayload).to.have.property('requestId').that.equals(bids_timeouted[0].auctionId); expect(notificationPayload).to.have.property('adUnit').that.deep.equals([bids_timeouted[0].adUnitCode, bids_timeouted[1].adUnitCode]); }); }); });