it('should attach request data', function () {
   const width = 300;
   const height = 250;
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = {
     banner: {
       sizes: [ width, height ]
     }
   };
   const topLocation = parseUrl('http://www.example.com?foo=bar', { decodeSearchAsString: true });
   const bidderRequest = {
     refererInfo: {
       referer: topLocation.href
     }
   };
   const requests = spec.buildRequests([ bidRequest ], bidderRequest);
   const data = requests[0].data;
   expect(data.slots).to.deep.equal([
     {
       slot: bidRequest.adUnitCode,
       id: bidRequest.params.appId,
       bidfloor: bidRequest.params.bidfloor,
       sizes: [{ w: width, h: height }]
     }
   ]);
   expect(data.page).to.equal(topLocation.href);
   expect(data.domain).to.equal(topLocation.hostname);
   expect(data.search).to.equal(topLocation.search);
   expect(data.ua).to.equal(navigator.userAgent);
 });
 it('should attach request data', function () {
   const width = 640;
   const height = 480;
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = {
     video: {
       playerSize: [ width, height ]
     }
   };
   const topLocation = parseUrl('http://www.example.com?foo=bar', { decodeSearchAsString: true });
   const bidderRequest = {
     refererInfo: {
       referer: topLocation.href
     }
   };
   const requests = spec.buildRequests([ bidRequest ], bidderRequest);
   const data = requests[0].data;
   expect(data.isPrebid).to.equal(true);
   expect(data.appId).to.equal(bidRequest.params.appId);
   expect(data.domain).to.equal(document.location.hostname);
   expect(data.id).to.be.a('string');
   expect(data.imp[0].video).to.deep.contain({ w: width, h: height, mimes: DEFAULT_MIMES });
   expect(data.imp[0].bidfloor).to.equal(bidRequest.params.bidfloor);
   expect(data.site).to.deep.equal({ page: topLocation.href, domain: topLocation.hostname });
   expect(data.device).to.deep.contain({ ua: navigator.userAgent, language: navigator.language, js: 1 });
   expect(data.cur).to.deep.equal(['USD']);
 });
 it('should return false when the "appId" param is missing', function () {
   const bidRequest = bidRequests[0];
   bidRequest.params = {
     bidfloor: 5.00
   };
   expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
 });
 it('should attach the bid request object', function () {
   bidRequests[0].mediaTypes = { video: {} };
   bidRequests[1].mediaTypes = { video: {} };
   const requests = spec.buildRequests(bidRequests);
   expect(requests[0].bidRequest).to.equal(bidRequests[0]);
   expect(requests[1].bidRequest).to.equal(bidRequests[1]);
 });
 it('should create a POST request for each bid', function () {
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = { video: {} };
   const requests = spec.buildRequests([ bidRequest ]);
   expect(requests[0].method).to.equal('POST');
   expect(requests[0].url).to.equal(VIDEO_ENDPOINT + bidRequest.params.appId);
 });
 it('should create a POST request for each bid format', function () {
   const width = 300;
   const height = 250;
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = {
     video: {
       playerSize: [ width, height ]
     },
     banner: {
       sizes: [ width, height ]
     }
   };
   bidRequest.params = {
     video: {
       bidfloor: 2.00,
       appId: '11bc5dd5-7421-4dd8-c926-40fa653bec76'
     },
     banner: {
       bidfloor: 1.00,
       appId: '3b16770b-17af-4d22-daff-9606bdf2c9c3'
     }
   };
   const requests = spec.buildRequests([ bidRequest ]);
   expect(requests.length).to.equal(2);
   expect(requests[0].url).to.contain(VIDEO_ENDPOINT);
   expect(requests[1].url).to.contain(BANNER_ENDPOINT);
 });
 it('should attach request data', () => {
   const width = 300;
   const height = 250;
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = {
     banner: {
       sizes: [ width, height ]
     }
   };
   const requests = spec.buildRequests([ bidRequest ]);
   const data = requests[0].data;
   const topLocation = utils.getTopWindowLocation();
   expect(data.slots).to.deep.equal([
     {
       slot: bidRequest.adUnitCode,
       id: bidRequest.params.appId,
       bidfloor: bidRequest.params.bidfloor,
       sizes: [{ w: width, h: height }]
     }
   ]);
   expect(data.page).to.equal(topLocation.href);
   expect(data.domain).to.equal(topLocation.hostname);
   expect(data.search).to.equal(topLocation.search);
   expect(data.ua).to.equal(navigator.userAgent);
 });
 it('should return a valid video bid response', function () {
   const width = 640;
   const height = 480;
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = {
     video: {
       playerSize: [ width, height ]
     }
   };
   const serverResponse = {
     bidPrice: 5.00,
     url: 'http://reachms.bfmio.com/getmu?aid=bid:19c4a196-fb21-4c81-9a1a-ecc5437a39da',
     cmpId: '123abc'
   };
   const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest });
   expect(bidResponse).to.deep.equal({
     requestId: bidRequest.bidId,
     bidderCode: spec.code,
     cpm: serverResponse.bidPrice,
     creativeId: serverResponse.cmpId,
     vastUrl: serverResponse.url,
     width: width,
     height: height,
     renderer: null,
     mediaType: 'video',
     currency: 'USD',
     netRevenue: true,
     ttl: 300
   });
 });
 it('should return false when the "bidfloor" param is missing', function () {
   const bidRequest = bidRequests[0];
   bidRequest.params = {
     appId: '11bc5dd5-7421-4dd8-c926-40fa653bec76'
   };
   expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
 });
 it('should create a single POST request for all bids', function () {
   bidRequests[0].mediaTypes = { banner: {} };
   bidRequests[1].mediaTypes = { banner: {} };
   const requests = spec.buildRequests(bidRequests);
   expect(requests.length).to.equal(1);
   expect(requests[0].method).to.equal('POST');
   expect(requests[0].url).to.equal(BANNER_ENDPOINT);
 });
 it('should return no bids if the response "url" is missing', function () {
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = { video: {} };
   const serverResponse = {
     bidPrice: 5.00
   };
   const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest });
   expect(bidResponse.length).to.equal(0);
 });
 it('should return no bids if the response "bidPrice" is missing', function () {
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = { video: {} };
   const serverResponse = {
     url: 'http://reachms.bfmio.com/getmu?aid=bid:19c4a196-fb21-4c81-9a1a-ecc5437a39da'
   };
   const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest });
   expect(bidResponse.length).to.equal(0);
 });
 it('must override video targeting params', () => {
   const bidRequest = bidRequests[0];
   const mimes = ['video/webm'];
   bidRequest.mediaTypes = { video: {} };
   bidRequest.params.video = { mimes };
   const requests = spec.buildRequests([ bidRequest ]);
   const data = requests[0].data;
   expect(data.imp[0].video).to.deep.contain({ mimes });
 });
 it('must fall back to the size on the bid object', function () {
   const width = 300;
   const height = 250;
   const bidRequest = bidRequests[0];
   bidRequest.sizes = [ width, height ];
   bidRequest.mediaTypes = { banner: {} };
   const requests = spec.buildRequests([ bidRequest ]);
   const data = requests[0].data;
   expect(data.slots[0].sizes).to.deep.contain({ w: width, h: height });
 });
 it('must fall back to the size on the bid object', function () {
   const width = 640;
   const height = 480;
   const bidRequest = bidRequests[0];
   bidRequest.sizes = [ width, height ];
   bidRequest.mediaTypes = { video: {} };
   const requests = spec.buildRequests([ bidRequest ]);
   const data = requests[0].data;
   expect(data.imp[0].video).to.deep.contain({ w: width, h: height });
 });
 it('should not return user syncs if none are enabled', function () {
   const syncOptions = {
     iframeEnabled: false,
     pixelEnabled: false
   };
   const serverResponses = [{
     body: bidResponse
   }];
   const userSyncs = spec.getUserSyncs(syncOptions, serverResponses);
   expect(userSyncs).to.deep.equal([]);
 });
 it('must handle an empty bid size', function () {
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = {
     video: {
       playerSize: []
     }
   };
   const requests = spec.buildRequests([ bidRequest ]);
   const data = requests[0].data;
   expect(data.imp[0].video).to.deep.contain({ w: undefined, h: undefined });
 });
 it('must override video targeting params', function () {
   const bidRequest = bidRequests[0];
   const mimes = ['video/webm'];
   const playbackmethod = 2;
   const maxduration = 30;
   bidRequest.mediaTypes = { video: {} };
   bidRequest.params.video = { mimes, playbackmethod, maxduration };
   const requests = spec.buildRequests([ bidRequest ]);
   const data = requests[0].data;
   expect(data.imp[0].video).to.deep.contain({ mimes, playbackmethod, maxduration });
 });
 it('must handle an empty bid size', function () {
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = {
     banner: {
       sizes: []
     }
   };
   const requests = spec.buildRequests([ bidRequest ]);
   const data = requests[0].data;
   expect(data.slots[0].sizes).to.deep.equal([]);
 });
 it('should return an image user sync if iframes are disabled', function () {
   const syncOptions = {
     iframeEnabled: false,
     pixelEnabled: true
   };
   const serverResponses = [{
     body: bidResponse
   }];
   const userSyncs = spec.getUserSyncs(syncOptions, serverResponses);
   expect(userSyncs.length).to.equal(1);
   expect(userSyncs[0].type).to.equal('image');
 });
 it('should return false when the required params are missing for video', () => {
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = {
     video: {}
   };
   bidRequest.params = {
     banner: {
       bidfloor: 1.00,
       appId: '3b16770b-17af-4d22-daff-9606bdf2c9c3'
     }
   };
   expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
 });
 it('must parse bid size from a string', function () {
   const width = 640;
   const height = 480;
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = {
     video: {
       playerSize: `${width}x${height}`
     }
   };
   const requests = spec.buildRequests([ bidRequest ]);
   const data = requests[0].data;
   expect(data.imp[0].video).to.deep.contain({ w: width, h: height });
 });
 it('should return true when the required params are passed for banner', function () {
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = {
     banner: {}
   };
   bidRequest.params = {
     banner: {
       bidfloor: 1.00,
       appId: '3b16770b-17af-4d22-daff-9606bdf2c9c3'
     }
   };
   expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
 });
 it('should not return user syncs if there are none in the bid response', function () {
   const syncOptions = {
     iframeEnabled: true,
     pixelEnabled: true
   };
   const serverResponses = [{
     body: [
       bidResponse
     ]
   }];
   const userSyncs = spec.getUserSyncs(syncOptions, serverResponses);
   expect(userSyncs).to.deep.equal([]);
 });
 it('must parse bid size from a nested array', () => {
   const width = 640;
   const height = 480;
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = {
     video: {
       playerSize: [[ width, height ]]
     }
   };
   const requests = spec.buildRequests([ bidRequest ]);
   const data = requests[0].data;
   expect(data.imp[0].video).to.deep.contain({ w: width, h: height });
 });
 it('should not return user syncs if iframes are disabled', function () {
   const syncUrl = 'http://sync.bfmio.com/sync_iframe?ifpl=5&ifg=1&id=test&gdpr=0&gc=&gce=0';
   const syncOptions = {
     iframeEnabled: false,
     pixelEnabled: true
   };
   const serverResponses = [{
     body: [
       { sync: syncUrl },
       bidResponse
     ]
   }];
   const userSyncs = spec.getUserSyncs(syncOptions, serverResponses);
   expect(userSyncs).to.deep.equal([]);
 });
 it('must parse bid size from a nested array', () => {
   const width = 300;
   const height = 250;
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = {
     banner: {
       sizes: [[ width, height ]]
     }
   };
   const requests = spec.buildRequests([ bidRequest ]);
   const data = requests[0].data;
   expect(data.slots[0].sizes).to.deep.equal([
     { w: width, h: height }
   ]);
 });
 it('must parse bid size from a string', function () {
   const width = 300;
   const height = 250;
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = {
     banner: {
       sizes: `${width}x${height}`
     }
   };
   const requests = spec.buildRequests([ bidRequest ]);
   const data = requests[0].data;
   expect(data.slots[0].sizes).to.deep.equal([
     { w: width, h: height }
   ]);
 });
 it('must add GDPR consent data to the request', function () {
   const bidRequest = bidRequests[0];
   bidRequest.mediaTypes = { banner: {} };
   const consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==';
   const bidderRequest = {
     gdprConsent: {
       gdprApplies: true,
       consentString
     }
   };
   const requests = spec.buildRequests([ bidRequest ], bidderRequest);
   const data = requests[0].data;
   expect(data.gdpr).to.equal(1);
   expect(data.gdprConsent).to.equal(consentString);
 });
 it('should return user syncs defined the bid response', function () {
   const syncUrl = 'http://sync.bfmio.com/sync_iframe?ifpl=5&ifg=1&id=test&gdpr=0&gc=&gce=0';
   const syncOptions = {
     iframeEnabled: true,
     pixelEnabled: true
   };
   const serverResponses = [{
     body: [
       { sync: syncUrl },
       bidResponse
     ]
   }];
   const userSyncs = spec.getUserSyncs(syncOptions, serverResponses);
   expect(userSyncs).to.deep.equal([
     { type: 'iframe', url: syncUrl }
   ]);
 });