UNPKG

mk9-prebid

Version:

Header Bidding Management Library

458 lines (445 loc) 13.9 kB
import {expect} from 'chai'; import {spec} from 'modules/feedadBidAdapter.js'; import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes.js'; import {server} from 'test/mocks/xhr.js'; const CODE = 'feedad'; describe('FeedAdAdapter', function () { describe('Public API', function () { it('should have the FeedAd bidder code', function () { expect(spec.code).to.equal(CODE); }); it('should only support video and banner ads', function () { expect(spec.supportedMediaTypes).to.be.a('array'); expect(spec.supportedMediaTypes).to.include(BANNER); expect(spec.supportedMediaTypes).not.to.include(VIDEO); expect(spec.supportedMediaTypes).not.to.include(NATIVE); }); it('should export the BidderSpec functions', function () { expect(spec.isBidRequestValid).to.be.a('function'); expect(spec.buildRequests).to.be.a('function'); expect(spec.interpretResponse).to.be.a('function'); expect(spec.onTimeout).to.be.a('function'); expect(spec.onBidWon).to.be.a('function'); }); it('should export the TCF vendor ID', function () { expect(spec.gvlid).to.equal(781); }) }); describe('isBidRequestValid', function () { it('should detect missing params', function () { let result = spec.isBidRequestValid({ bidder: 'feedad', sizes: [] }); expect(result).to.equal(false); }); it('should detect missing client token', function () { let result = spec.isBidRequestValid({ bidder: 'feedad', sizes: [], params: {placementId: 'placement'} }); expect(result).to.equal(false); }); it('should detect zero length client token', function () { let result = spec.isBidRequestValid({ bidder: 'feedad', sizes: [], params: {clientToken: '', placementId: 'placement'} }); expect(result).to.equal(false); }); it('should detect missing placement id', function () { let result = spec.isBidRequestValid({ bidder: 'feedad', sizes: [], params: {clientToken: 'clientToken'} }); expect(result).to.equal(false); }); it('should detect zero length placement id', function () { let result = spec.isBidRequestValid({ bidder: 'feedad', sizes: [], params: {clientToken: 'clientToken', placementId: ''} }); expect(result).to.equal(false); }); it('should detect too long placement id', function () { var placementId = ''; for (var i = 0; i < 300; i++) { placementId += 'a'; } let result = spec.isBidRequestValid({ bidder: 'feedad', sizes: [], params: {clientToken: 'clientToken', placementId} }); expect(result).to.equal(false); }); it('should detect invalid placement id', function () { [ 'placement id with spaces', 'some|id', 'PLACEMENTID', 'placeme:ntId' ].forEach(id => { let result = spec.isBidRequestValid({ bidder: 'feedad', sizes: [], params: {clientToken: 'clientToken', placementId: id} }); expect(result).to.equal(false); }); }); it('should accept valid parameters', function () { let result = spec.isBidRequestValid({ bidder: 'feedad', sizes: [], params: {clientToken: 'clientToken', placementId: 'placement-id'} }); expect(result).to.equal(true); }); }); describe('buildRequests', function () { const bidderRequest = { refererInfo: { referer: 'the referer' }, some: 'thing' }; it('should accept empty lists', function () { let result = spec.buildRequests([], bidderRequest); expect(result).to.be.empty; }); it('should filter native media types', function () { let bid = { code: 'feedad', mediaTypes: { native: { sizes: [[300, 250], [300, 600]], } }, params: {clientToken: 'clientToken', placementId: 'placement-id'} }; let result = spec.buildRequests([bid], bidderRequest); expect(result).to.be.empty; }); it('should filter video media types without outstream context', function () { let bid = { code: 'feedad', mediaTypes: { video: { context: 'instream' } }, params: {clientToken: 'clientToken', placementId: 'placement-id'} }; let result = spec.buildRequests([bid], bidderRequest); expect(result).to.be.empty; }); it('should pass through outstream video media', function () { let bid = { code: 'feedad', mediaTypes: { video: { context: 'outstream' } }, params: {clientToken: 'clientToken', placementId: 'placement-id'} }; let result = spec.buildRequests([bid], bidderRequest); expect(result.data.bids).to.be.lengthOf(1); expect(result.data.bids[0]).to.deep.equal(bid); }); it('should pass through banner media', function () { let bid = { code: 'feedad', mediaTypes: { banner: { sizes: [[320, 250]] } }, params: {clientToken: 'clientToken', placementId: 'placement-id'} }; let result = spec.buildRequests([bid], bidderRequest); expect(result.data.bids).to.be.lengthOf(1); expect(result.data.bids[0]).to.deep.equal(bid); }); it('should detect empty media types', function () { let bid = { code: 'feedad', mediaTypes: { banner: undefined, video: undefined, native: undefined }, params: {clientToken: 'clientToken', placementId: 'placement-id'} }; let result = spec.buildRequests([bid], bidderRequest); expect(result).to.be.empty; }); it('should use POST', function () { let bid = { code: 'feedad', mediaTypes: { banner: { sizes: [[320, 250]] } }, params: {clientToken: 'clientToken', placementId: 'placement-id'} }; let result = spec.buildRequests([bid], bidderRequest); expect(result.method).to.equal('POST'); }); it('should use the correct URL', function () { let bid = { code: 'feedad', mediaTypes: { banner: { sizes: [[320, 250]] } }, params: {clientToken: 'clientToken', placementId: 'placement-id'} }; let result = spec.buildRequests([bid], bidderRequest); expect(result.url).to.equal('https://api.feedad.com/1/prebid/web/bids'); }); it('should specify the content type explicitly', function () { let bid = { code: 'feedad', mediaTypes: { banner: { sizes: [[320, 250]] } }, params: {clientToken: 'clientToken', placementId: 'placement-id'} }; let result = spec.buildRequests([bid], bidderRequest); expect(result.options).to.deep.equal({ contentType: 'application/json' }) }); it('should include the bidder request', function () { let bid = { code: 'feedad', mediaTypes: { banner: { sizes: [[320, 250]] } }, params: {clientToken: 'clientToken', placementId: 'placement-id'} }; let result = spec.buildRequests([bid, bid, bid], bidderRequest); expect(result.data).to.deep.include(bidderRequest); }); it('should detect missing bidder request parameter', function () { let bid = { code: 'feedad', mediaTypes: { banner: { sizes: [[320, 250]] } }, params: {clientToken: 'clientToken', placementId: 'placement-id'} }; let result = spec.buildRequests([bid, bid, bid]); expect(result).to.be.empty; }); it('should not include GDPR data if the bidder request has none available', function () { let bid = { code: 'feedad', mediaTypes: { banner: { sizes: [[320, 250]] } }, params: {clientToken: 'clientToken', placementId: 'placement-id'} }; let result = spec.buildRequests([bid], bidderRequest); expect(result.data.gdprApplies).to.be.undefined; expect(result.data.consentIabTcf).to.be.undefined; }); it('should include GDPR data if the bidder requests contains it', function () { let bid = { code: 'feedad', mediaTypes: { banner: { sizes: [[320, 250]] } }, params: {clientToken: 'clientToken', placementId: 'placement-id'} }; let request = Object.assign({}, bidderRequest, { gdprConsent: { consentString: 'the consent string', gdprApplies: true } }); let result = spec.buildRequests([bid], request); expect(result.data.gdprApplies).to.equal(request.gdprConsent.gdprApplies); expect(result.data.consentIabTcf).to.equal(request.gdprConsent.consentString); }); }); describe('interpretResponse', function () { const body = [{ foo: 'bar', sub: { obj: 5 } }, { bar: 'foo' }]; it('should convert string bodies to JSON', function () { let result = spec.interpretResponse({body: JSON.stringify(body)}); expect(result).to.deep.equal(body); }); it('should pass through body objects', function () { let result = spec.interpretResponse({body}); expect(result).to.deep.equal(body); }); }); describe('event tracking calls', function () { const clientToken = 'clientToken'; const placementId = 'placement id'; const auctionId = 'the auction id'; const bidId = 'the bid id'; const transactionId = 'the transaction id'; const referer = 'the referer'; const bidderRequest = { refererInfo: { referer: referer }, some: 'thing' }; const bid = { 'bidder': 'feedad', 'params': { 'clientToken': 'fupp', 'placementId': 'prebid-test' }, 'crumbs': { 'pubcid': '6254a85f-bded-489a-9736-83c45d45ef1d' }, 'mediaTypes': { 'banner': { 'sizes': [ [ 300, 250 ] ] } }, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': transactionId, 'sizes': [ [ 300, 250 ] ], 'bidId': bidId, 'bidderRequestId': '10739fe6fe2127', 'auctionId': '5ac67dff-d971-4b56-84a3-345a87a1f786', 'src': 'client', 'bidRequestsCount': 1 }; const timeoutData = { 'bidId': bidId, 'bidder': 'feedad', 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'auctionId': auctionId, 'params': [ { 'clientToken': clientToken, 'placementId': placementId } ], 'timeout': 3000 }; const bidWonData = { 'bidderCode': 'feedad', 'width': 300, 'height': 250, 'statusMessage': 'Bid available', 'adId': '3a4529aa05114d', 'requestId': bidId, 'mediaType': 'banner', 'source': 'client', 'cpm': 0.5, 'ad': 'ad content', 'ttl': 60, 'creativeId': 'feedad-21-0', 'netRevenue': true, 'currency': 'EUR', 'auctionId': auctionId, 'responseTimestamp': 1558365914596, 'requestTimestamp': 1558365914506, 'bidder': 'feedad', 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'timeToRespond': 90, 'pbLg': '0.50', 'pbMg': '0.50', 'pbHg': '0.50', 'pbAg': '0.50', 'pbDg': '0.50', 'pbCg': '', 'size': '300x250', 'adserverTargeting': { 'hb_bidder': 'feedad', 'hb_adid': '3a4529aa05114d', 'hb_pb': '0.50', 'hb_size': '300x250', 'hb_source': 'client', 'hb_format': 'banner' }, 'status': 'rendered', 'params': [ { 'clientToken': clientToken, 'placementId': placementId } ] }; const cases = [ ['onTimeout', timeoutData, 'prebid_bidTimeout'], ['onBidWon', bidWonData, 'prebid_bidWon'], ]; cases.forEach(([name, data, eventKlass]) => { let subject = spec[name]; describe(name + ' handler', function () { it('should do nothing on empty data', function () { subject(undefined); subject(null); expect(server.requests.length).to.equal(0); }); it('should do nothing when bid metadata is not set', function () { subject(data); expect(server.requests.length).to.equal(0); }); it('should send tracking params when correct metadata was set', function () { spec.buildRequests([bid], bidderRequest); let expectedData = { app_hybrid: false, client_token: clientToken, placement_id: placementId, klass: eventKlass, prebid_auction_id: auctionId, prebid_bid_id: bidId, prebid_transaction_id: transactionId, referer, sdk_version: '1.0.2' }; subject(data); expect(server.requests.length).to.equal(1); let call = server.requests[0]; expect(call.url).to.equal('https://api.feedad.com/1/prebid/web/events'); expect(JSON.parse(call.requestBody)).to.deep.equal(expectedData); expect(call.method).to.equal('POST'); expect(call.requestHeaders).to.include({'Content-Type': 'application/json;charset=utf-8'}); }) }); }); }); });