UNPKG

mk9-prebid

Version:

Header Bidding Management Library

378 lines (335 loc) 11.6 kB
import { expect } from 'chai'; import { spec } from 'modules/inskinBidAdapter.js'; import { createBid } from 'src/bidfactory.js'; const ENDPOINT = 'https://mfad.inskinad.com/api/v2'; const REQUEST = { 'bidderCode': 'inskin', 'requestId': 'a4713c32-3762-4798-b342-4ab810ca770d', 'bidderRequestId': '109f2a181342a9', 'bidRequest': [{ 'bidder': 'inskin', 'params': { 'networkId': 9874, 'siteId': 730181 }, 'placementCode': 'div-gpt-ad-1487778092495-0', 'sizes': [ [728, 90], [970, 90] ], 'bidId': '2b0f82502298c9', 'bidderRequestId': '109f2a181342a9', 'requestId': 'a4713c32-3762-4798-b342-4ab810ca770d' }, { 'bidder': 'inskin', 'params': { 'networkId': 9874, 'siteId': 730181 }, 'placementCode': 'div-gpt-ad-1487778092495-0', 'sizes': [ [728, 90], [970, 90] ], 'bidId': '123', 'bidderRequestId': '109f2a181342a9', 'requestId': 'a4713c32-3762-4798-b342-4ab810ca770d' }], 'start': 1487883186070, 'auctionStart': 1487883186069, 'timeout': 3000 }; const RESPONSE = { 'headers': null, 'body': { 'user': { 'key': 'ue1-2d33e91b71e74929b4aeecc23f4376f1' }, 'decisions': { '2b0f82502298c9': { 'adId': 2364764, 'creativeId': 1950991, 'flightId': 2788300, 'campaignId': 542982, 'clickUrl': 'https://mfad.inskinad.com/r', 'impressionUrl': 'https://mfad.inskinad.com/i.gif', 'contents': [{ 'type': 'html', 'body': '<html></html>', 'data': { 'height': 90, 'width': 728, 'imageUrl': 'https://static.adzerk.net/Advertisers/b0ab77db8a7848c8b78931aed022a5ef.gif', 'fileName': 'b0ab77db8a7848c8b78931aed022a5ef.gif' }, 'template': 'image' }], 'height': 90, 'width': 728, 'events': [], 'pricing': {'price': 0.5, 'clearPrice': 0.5, 'revenue': 0.0005, 'rateType': 2, 'eCPM': 0.5} }, '123': { 'adId': 2364764, 'creativeId': 1950991, 'flightId': 2788300, 'campaignId': 542982, 'clickUrl': 'https://mfad.inskinad.com/r', 'impressionUrl': 'https://mfad.inskinad.com/i.gif', 'contents': [{ 'type': 'html', 'body': '<html></html>', 'data': { 'customData': { 'pubCPM': 1 }, 'height': 90, 'width': 728, 'imageUrl': 'https://static.adzerk.net/Advertisers/b0ab77db8a7848c8b78931aed022a5ef.gif', 'fileName': 'b0ab77db8a7848c8b78931aed022a5ef.gif' }, 'template': 'image' }], 'height': 90, 'width': 728, 'events': [], 'pricing': {'price': 0.5, 'clearPrice': 0.5, 'revenue': 0.0005, 'rateType': 2, 'eCPM': 0.5} } } } }; const consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; const bidderRequest = { bidderCode: 'inskin', gdprConsent: { consentString: consentString, gdprApplies: true }, refererInfo: { referer: 'https://www.inskinmedia.com' } }; describe('InSkin BidAdapter', function () { let bidRequests; let adapter = spec; beforeEach(function () { bidRequests = [ { bidder: 'inskin', params: { networkId: '9874', siteId: 'xxxxx' }, placementCode: 'header-bid-tag-1', sizes: [[300, 250], [300, 600]], bidId: '23acc48ad47af5', requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', bidderRequestId: '1c56ad30b9b8ca8', transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' } ]; }); describe('bid request validation', function () { it('should accept valid bid requests', function () { let bid = { bidder: 'inskin', params: { networkId: '9874', siteId: 'xxxxx' } }; expect(spec.isBidRequestValid(bid)).to.equal(true); }); it('should accept valid bid requests with extra fields', function () { let bid = { bidder: 'inskin', params: { networkId: '9874', siteId: 'xxxxx', zoneId: 'xxxxx' } }; expect(spec.isBidRequestValid(bid)).to.equal(true); }); it('should reject bid requests without siteId', function () { let bid = { bidder: 'inskin', params: { networkId: '9874' } }; expect(spec.isBidRequestValid(bid)).to.equal(false); }); it('should reject bid requests without networkId', function () { let bid = { bidder: 'inskin', params: { siteId: '9874' } }; expect(spec.isBidRequestValid(bid)).to.equal(false); }); }); describe('buildRequests validation', function () { it('creates request data', function () { let request = spec.buildRequests(bidRequests, bidderRequest); expect(request).to.exist.and.to.be.a('object'); }); it('request to inskin should contain a url', function () { let request = spec.buildRequests(bidRequests, bidderRequest); expect(request.url).to.have.string('inskinad.com'); }); it('requires valid bids to make request', function () { let request = spec.buildRequests([], bidderRequest); expect(request.bidRequest).to.be.empty; }); it('sends bid request to ENDPOINT via POST', function () { let request = spec.buildRequests(bidRequests, bidderRequest); expect(request.method).to.have.string('POST'); }); it('should add gdpr consent information to the request', function () { bidderRequest.bids = bidRequests; const request = spec.buildRequests(bidRequests, bidderRequest); const payload = JSON.parse(request.data); expect(payload.consent.gdprConsentString).to.exist; expect(payload.consent.gdprConsentRequired).to.exist; expect(payload.consent.gdprConsentString).to.exist.and.to.equal(consentString); expect(payload.consent.gdprConsentRequired).to.exist.and.to.be.true; }); it('should not add keywords if TCF v2 purposes are granted', function () { const bidderRequest2 = Object.assign({}, bidderRequest, { gdprConsent: { gdprApplies: true, consentString: 'consentString', vendorData: { vendor: { consents: { 150: true } }, purpose: { consents: { 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true } } }, apiVersion: 2 } }); const request = spec.buildRequests(bidRequests, bidderRequest2); const payload = JSON.parse(request.data); expect(payload.keywords).to.be.an('array').that.is.empty; expect(payload.placements[0].properties.restrictions).to.be.undefined; }); it('should add keywords if TCF v2 purposes are not granted', function () { const bidderRequest2 = Object.assign({}, bidderRequest, { gdprConsent: { gdprApplies: true, consentString: 'consentString', vendorData: { vendor: { consents: { 150: false } }, purpose: { consents: { 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true } } }, apiVersion: 2 } }); const request = spec.buildRequests(bidRequests, bidderRequest2); const payload = JSON.parse(request.data); expect(payload.keywords).to.be.an('array').that.includes('cst-nocookies'); expect(payload.keywords).to.be.an('array').that.includes('cst-nocontext'); expect(payload.keywords).to.be.an('array').that.includes('cst-nodmp'); expect(payload.keywords).to.be.an('array').that.includes('cst-nodata'); expect(payload.keywords).to.be.an('array').that.includes('cst-noclicks'); expect(payload.keywords).to.be.an('array').that.includes('cst-noresearch'); expect(payload.placements[0].properties.restrictions).to.be.an('array').that.includes('nocookies'); expect(payload.placements[0].properties.restrictions).to.be.an('array').that.includes('nocontext'); expect(payload.placements[0].properties.restrictions).to.be.an('array').that.includes('nodmp'); expect(payload.placements[0].properties.restrictions).to.be.an('array').that.includes('nodata'); expect(payload.placements[0].properties.restrictions).to.be.an('array').that.includes('noclicks'); expect(payload.placements[0].properties.restrictions).to.be.an('array').that.includes('noresearch'); }); }); describe('interpretResponse validation', function () { it('response should have valid bidderCode', function () { let bidRequest = spec.buildRequests(REQUEST.bidRequest, bidderRequest); let bid = createBid(1, bidRequest.bidRequest[0]); expect(bid.bidderCode).to.equal('inskin'); }); it('response should include objects for all bids', function () { let bids = spec.interpretResponse(RESPONSE, REQUEST); expect(bids.length).to.equal(2); }); it('registers bids', function () { let bids = spec.interpretResponse(RESPONSE, REQUEST); bids.forEach(b => { expect(b).to.have.property('cpm'); expect(b.cpm).to.be.above(0); expect(b).to.have.property('requestId'); expect(b).to.have.property('cpm'); expect(b).to.have.property('width'); expect(b).to.have.property('height'); expect(b).to.have.property('ad'); expect(b).to.have.property('currency', 'USD'); expect(b).to.have.property('creativeId'); expect(b).to.have.property('ttl', 360); expect(b.meta).to.have.property('advertiserDomains'); expect(b).to.have.property('netRevenue', true); }); }); it('cpm is correctly set', function () { let bids = spec.interpretResponse(RESPONSE, REQUEST); expect(bids[0].cpm).to.equal(0.5); expect(bids[1].cpm).to.equal(1); }); it('handles nobid responses', function () { let EMPTY_RESP = Object.assign({}, RESPONSE, {'body': {'decisions': null}}) let bids = spec.interpretResponse(EMPTY_RESP, REQUEST); expect(bids).to.be.empty; }); it('handles no server response', function () { let bids = spec.interpretResponse(null, REQUEST); expect(bids).to.be.empty; }); }); describe('getUserSyncs', function () { it('handles empty sync options', function () { let opts = spec.getUserSyncs({}); expect(opts).to.be.empty; }); it('should return two sync urls if pixel syncs are enabled', function () { let syncOptions = {'pixelEnabled': true}; let opts = spec.getUserSyncs(syncOptions); expect(opts.length).to.equal(2); }); it('should return three sync urls if pixel and iframe syncs are enabled', function () { let syncOptions = {'iframeEnabled': true, 'pixelEnabled': true}; let opts = spec.getUserSyncs(syncOptions); expect(opts.length).to.equal(3); }); }); });