From 67fb91bf6e2d11c6cf4d3d74b42362928f06b6de Mon Sep 17 00:00:00 2001
From: Chandra Prakash <chandra.prakash@advangelists.com>
Date: Tue, 26 Feb 2019 13:50:33 -0800
Subject: [PATCH 1/3] Submit Advangelists Prebid Adapter

---
 modules/advangelistsBidAdapter.js        | 443 +++++++++++++++++++++++
 modules/advangelistsBidAdapter.md        |  65 ++++
 test/spec/advangelistsBidAdapter_spec.js | 141 ++++++++
 3 files changed, 649 insertions(+)
 create mode 100644 modules/advangelistsBidAdapter.js
 create mode 100644 modules/advangelistsBidAdapter.md
 create mode 100644 test/spec/advangelistsBidAdapter_spec.js

diff --git a/modules/advangelistsBidAdapter.js b/modules/advangelistsBidAdapter.js
new file mode 100644
index 00000000000..d0298db4e1c
--- /dev/null
+++ b/modules/advangelistsBidAdapter.js
@@ -0,0 +1,443 @@
+import * as utils from '../src/utils';
+import { parse as parseUrl } from '../src/url';
+import { config } from '../src/config';
+import { registerBidder } from '../src/adapters/bidderFactory';
+// import { Renderer } from '../src/Renderer';
+import { VIDEO, BANNER } from '../src/mediaTypes';
+import find from 'core-js/library/fn/array/find';
+import includes from 'core-js/library/fn/array/includes';
+
+const ADAPTER_VERSION = '1.0';
+const BIDDER_CODE = 'avng';
+// const OUTSTREAM = 'outstream';
+
+export const VIDEO_ENDPOINT = '//nep.advangelists.com/xp/get?pubid=';// 0cf8d6d643e13d86a5b6374148a4afac';
+export const BANNER_ENDPOINT = '//nep.advangelists.com/xp/get?pubid=';// 0cf8d6d643e13d86a5b6374148a4afac';
+export const OUTSTREAM_SRC = '//player-cdn.beachfrontmedia.com/playerapi/loader/outstream.js';
+
+export const VIDEO_TARGETING = ['mimes', 'playbackmethod', 'maxduration', 'skip'];
+export const DEFAULT_MIMES = ['video/mp4', 'application/javascript'];
+
+let pubid = '';
+
+export const spec = {
+  code: BIDDER_CODE,
+  supportedMediaTypes: [BANNER, VIDEO],
+
+  isBidRequestValid(bidRequest) {
+    if (typeof bidRequest != 'undefined') {
+      if (bidRequest.bidder !== BIDDER_CODE && typeof bidRequest.params === 'undefined') { return false; }
+      if (bidRequest === '' || bidRequest.params.placement === '' || bidRequest.params.pubid === '') { return false; }
+      return true;
+    } else { return false; }
+  },
+
+  buildRequests(bids, bidderRequest) {
+    let requests = [];
+    let videoBids = bids.filter(bid => isVideoBidValid(bid));
+    let bannerBids = bids.filter(bid => isBannerBidValid(bid));
+    videoBids.forEach(bid => {
+      pubid = getVideoBidParam(bid, 'pubid');
+      requests.push({
+        method: 'POST',
+        url: VIDEO_ENDPOINT + pubid,
+        data: createVideoRequestData(bid, bidderRequest),
+        bidRequest: bid
+      });
+    });
+
+    bannerBids.forEach(bid => {
+      pubid = getBannerBidParam(bid, 'pubid');
+      requests.push({
+        method: 'POST',
+        url: BANNER_ENDPOINT + pubid,
+        data: createBannerRequestData(bid, bidderRequest),
+        bidRequest: bid
+      });
+    });
+
+    console.log(requests);
+    return requests;
+  },
+
+  interpretResponse(serverResponse, {bidRequest}) {
+    let response = serverResponse.body;
+    if (response !== null && utils.isEmpty(response) == false) {
+      if (isVideoBid(bidRequest)) {
+        console.log('About to create final response for video')
+        let bidResponse = {
+          requestId: response.id,
+          bidderCode: BIDDER_CODE,
+          cpm: response.seatbid[0].bid[0].price,
+          width: response.seatbid[0].bid[0].w,
+          height: response.seatbid[0].bid[0].h,
+          ttl: response.seatbid[0].bid[0].ttl || 60,
+          creativeId: response.seatbid[0].bid[0].crid,
+          currency: response.cur,
+          mediaType: VIDEO,
+          netRevenue: true
+        }
+
+        if (response.seatbid[0].bid[0].adm) {
+          bidResponse.vastXml = response.seatbid[0].bid[0].adm;
+          bidResponse.adResponse = {
+            content: response.seatbid[0].bid[0].adm
+          };
+        } else {
+          bidResponse.vastUrl = response.seatbid[0].bid[0].nurl;
+        }
+
+        return bidResponse;
+      } else {
+        console.log('About to create final respsone for banner')
+        return {
+          requestId: response.id,
+          bidderCode: BIDDER_CODE,
+          cpm: response.seatbid[0].bid[0].price,
+          width: response.seatbid[0].bid[0].w,
+          height: response.seatbid[0].bid[0].h,
+          ad: response.seatbid[0].bid[0].adm,
+          ttl: response.seatbid[0].bid[0].ttl || 60,
+          creativeId: response.seatbid[0].bid[0].crid,
+          currency: response.cur,
+          mediaType: BANNER,
+          netRevenue: true
+        }
+      }
+    }
+  }
+/*,
+
+  getUserSyncs(syncOptions, serverResponses = [], gdprConsent = {}) {
+    let syncs = [];
+    let { gdprApplies, consentString } = gdprConsent;
+    let bannerResponse = find(serverResponses, (res) => utils.isArray(res.body));
+
+    if (bannerResponse) {
+      if (syncOptions.iframeEnabled) {
+        bannerResponse.body
+          .filter(bid => bid.sync)
+          .forEach(bid => {
+            syncs.push({
+              type: 'iframe',
+              url: bid.sync
+            });
+          });
+      }
+    } else if (syncOptions.iframeEnabled) {
+      syncs.push({
+        type: 'iframe',
+        url: `//sync.bfmio.com/sync_iframe?ifg=1&id=${appId}&gdpr=${gdprApplies ? 1 : 0}&gc=${consentString || ''}&gce=1`
+      });
+    } else if (syncOptions.pixelEnabled) {
+      syncs.push({
+        type: 'image',
+        url: `//sync.bfmio.com/syncb?pid=144&id=${appId}&gdpr=${gdprApplies ? 1 : 0}&gc=${consentString || ''}&gce=1`
+      });
+    }
+
+    return syncs;
+  } */
+};
+
+function isBannerBid(bid) {
+  return utils.deepAccess(bid, 'mediaTypes.banner') || !isVideoBid(bid);
+}
+
+function isVideoBid(bid) {
+  return utils.deepAccess(bid, 'mediaTypes.video');
+}
+
+function isVideoBidValid(bid) {
+  return isVideoBid(bid) && getVideoBidParam(bid, 'pubid') && getVideoBidParam(bid, 'placement');
+}
+
+function isBannerBidValid(bid) {
+  return isBannerBid(bid) && getBannerBidParam(bid, 'pubid') && getBannerBidParam(bid, 'placement');
+}
+
+function getVideoBidParam(bid, key) {
+  return utils.deepAccess(bid, 'params.video.' + key) || utils.deepAccess(bid, 'params.' + key);
+}
+
+function getBannerBidParam(bid, key) {
+  return utils.deepAccess(bid, 'params.banner.' + key) || utils.deepAccess(bid, 'params.' + key);
+}
+
+function isMobile() {
+  return (/(ios|ipod|ipad|iphone|android)/i).test(navigator.userAgent);
+}
+
+function isConnectedTV() {
+  return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(navigator.userAgent);
+}
+
+function getDoNotTrack() {
+  return navigator.doNotTrack === '1' || window.doNotTrack === '1' || navigator.msDoNoTrack === '1' || navigator.doNotTrack === 'yes';
+}
+
+function findAndFillParam(o, key, value) {
+  try {
+    if (typeof value === 'function') {
+      o[key] = value();
+    } else {
+      o[key] = value;
+    }
+  } catch (ex) {}
+}
+
+/*
+function createRenderer(bidRequest) {
+  const renderer = Renderer.install({
+    id: bidRequest.bidId,
+    url: OUTSTREAM_SRC,
+    loaded: false
+  });
+
+  renderer.setRender(outstreamRender);
+
+  return renderer;
+}
+
+function outstreamRender(bid) {
+  bid.renderer.push(() => {
+    window.Beachfront.Player(bid.adUnitCode, {
+      ad_tag_url: bid.vastUrl,
+      width: bid.width,
+      height: bid.height,
+      expand_in_view: false,
+      collapse_on_complete: true
+    });
+  });
+}
+*/
+function getOsVersion() {
+  let clientStrings = [
+    { s: 'Android', r: /Android/ },
+    { s: 'iOS', r: /(iPhone|iPad|iPod)/ },
+    { s: 'Mac OS X', r: /Mac OS X/ },
+    { s: 'Mac OS', r: /(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/ },
+    { s: 'Linux', r: /(Linux|X11)/ },
+    { s: 'Windows 10', r: /(Windows 10.0|Windows NT 10.0)/ },
+    { s: 'Windows 8.1', r: /(Windows 8.1|Windows NT 6.3)/ },
+    { s: 'Windows 8', r: /(Windows 8|Windows NT 6.2)/ },
+    { s: 'Windows 7', r: /(Windows 7|Windows NT 6.1)/ },
+    { s: 'Windows Vista', r: /Windows NT 6.0/ },
+    { s: 'Windows Server 2003', r: /Windows NT 5.2/ },
+    { s: 'Windows XP', r: /(Windows NT 5.1|Windows XP)/ },
+    { s: 'UNIX', r: /UNIX/ },
+    { s: 'Search Bot', r: /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/ }
+  ];
+  let cs = find(clientStrings, cs => cs.r.test(navigator.userAgent));
+  return cs ? cs.s : 'unknown';
+}
+
+function getFirstSize(sizes) {
+  return (sizes && sizes.length) ? sizes[0] : { w: undefined, h: undefined };
+}
+
+function parseSizes(sizes) {
+  return utils.parseSizesInput(sizes).map(size => {
+    let [ width, height ] = size.split('x');
+    return {
+      w: parseInt(width, 10) || undefined,
+      h: parseInt(height, 10) || undefined
+    };
+  });
+}
+
+function getVideoSizes(bid) {
+  return parseSizes(utils.deepAccess(bid, 'mediaTypes.video.playerSize') || bid.sizes);
+}
+
+function getBannerSizes(bid) {
+  return parseSizes(utils.deepAccess(bid, 'mediaTypes.banner.sizes') || bid.sizes);
+}
+
+function getTopWindowReferrer() {
+  try {
+    return window.top.document.referrer;
+  } catch (e) {
+    return '';
+  }
+}
+
+function getVideoTargetingParams(bid) {
+  return Object.keys(Object(bid.params.video))
+    .filter(param => includes(VIDEO_TARGETING, param))
+    .reduce((obj, param) => {
+      obj[ param ] = bid.params.video[ param ];
+      return obj;
+    }, {});
+}
+
+function createVideoRequestData(bid, bidderRequest) {
+  let topLocation = getTopWindowLocation(bidderRequest);
+  let topReferrer = getTopWindowReferrer();
+
+  let sizes = getVideoSizes(bid);
+  let firstSize = getFirstSize(sizes);
+
+  let video = getVideoTargetingParams(bid);
+  var o = {
+    'device': {
+      'langauge': (global.navigator.language).split('-')[0],
+      'dnt': (global.navigator.doNotTrack === 1 ? 1 : 0),
+      'devicetype': isMobile() ? 4 : isConnectedTV() ? 3 : 2,
+      'js': 1,
+      'os': getOsVersion()
+    },
+    'at': 2,
+    'site': {},
+    'tmax': 3000,
+    'cur': ['USD'],
+    'id': bid.bidId,
+    'imp': [],
+    'regs': {
+      'ext': {
+      }
+    },
+    'user': {
+      'ext': {
+      }
+    }
+  };
+
+  o.site['page'] = topLocation.href;
+  o.site['domain'] = topLocation.hostname;
+  o.site['search'] = topLocation.search;
+  o.site['domain'] = topLocation.hostname;
+  o.site['ref'] = topReferrer;
+  o.site['mobile'] = isMobile() ? 1 : 0;
+  var secure = topLocation.protocol.indexOf('https') === 0 ? 1 : 0;
+
+  o.device['dnt'] = getDoNotTrack() ? 1 : 0;
+
+  findAndFillParam(o.site, 'name', function() {
+    return global.top.document.title;
+  });
+
+  findAndFillParam(o.device, 'h', function() {
+    return global.screen.height;
+  });
+  findAndFillParam(o.device, 'w', function() {
+    return global.screen.width;
+  });
+
+  let placement = getVideoBidParam(bid, 'placement');
+
+  for (let j = 0; j < sizes.length; j++) {
+    o.imp.push({
+      'id': '' + j,
+      'displaymanager': '' + BIDDER_CODE,
+      'displaymanagerver': '' + ADAPTER_VERSION,
+      'tagId': placement,
+      'bidfloor': 2.0,
+      'bidfloorcur': 'USD',
+      'secure': secure,
+      'video': Object.assign({
+        'id': utils.generateUUID(),
+        'pos': 0,
+        'w': firstSize.w,
+        'h': firstSize.h,
+        'mimes': DEFAULT_MIMES
+      }, video)
+
+    });
+  }
+
+  if (bidderRequest && bidderRequest.gdprConsent) {
+    let { gdprApplies, consentString } = bidderRequest.gdprConsent;
+    o.regs.ext = {'gdpr': gdprApplies ? 1 : 0};
+    o.user.ext = {'consent': consentString};
+  }
+
+  return o;
+}
+
+function getTopWindowLocation(bidderRequest) {
+  let url = bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer;
+  return parseUrl(config.getConfig('pageUrl') || url, { decodeSearchAsString: true });
+}
+
+function createBannerRequestData(bid, bidderRequest) {
+  let topLocation = getTopWindowLocation(bidderRequest);
+  let topReferrer = getTopWindowReferrer();
+
+  let sizes = getBannerSizes(bid);
+
+  var o = {
+    'device': {
+      'langauge': (global.navigator.language).split('-')[0],
+      'dnt': (global.navigator.doNotTrack === 1 ? 1 : 0),
+      'devicetype': isMobile() ? 4 : isConnectedTV() ? 3 : 2,
+      'js': 1
+    },
+    'at': 2,
+    'site': {},
+    'tmax': 3000,
+    'cur': ['USD'],
+    'id': bid.bidId,
+    'imp': [],
+    'regs': {
+      'ext': {
+      }
+    },
+    'user': {
+      'ext': {
+      }
+    }
+  };
+
+  o.site['page'] = topLocation.href;
+  o.site['domain'] = topLocation.hostname;
+  o.site['search'] = topLocation.search;
+  o.site['domain'] = topLocation.hostname;
+  o.site['ref'] = topReferrer;
+  o.site['mobile'] = isMobile() ? 1 : 0;
+  var secure = topLocation.protocol.indexOf('https') === 0 ? 1 : 0;
+
+  o.device['dnt'] = getDoNotTrack() ? 1 : 0;
+
+  findAndFillParam(o.site, 'name', function() {
+    return global.top.document.title;
+  });
+
+  findAndFillParam(o.device, 'h', function() {
+    return global.screen.height;
+  });
+  findAndFillParam(o.device, 'w', function() {
+    return global.screen.width;
+  });
+
+  let placement = getBannerBidParam(bid, 'placement');
+  for (let j = 0; j < sizes.length; j++) {
+    let size = sizes[j];
+
+    o.imp.push({
+      'id': '' + j,
+      'displaymanager': '' + BIDDER_CODE,
+      'displaymanagerver': '' + ADAPTER_VERSION,
+      'tagId': placement,
+      'bidfloor': 2.0,
+      'bidfloorcur': 'USD',
+      'secure': secure,
+      'banner': {
+        'id': utils.generateUUID(),
+        'pos': 0,
+        'w': size['w'],
+        'h': size['h']
+      }
+    });
+  }
+
+  if (bidderRequest && bidderRequest.gdprConsent) {
+    let { gdprApplies, consentString } = bidderRequest.gdprConsent;
+    o.regs.ext = {'gdpr': gdprApplies ? 1 : 0};
+    o.user.ext = {'consent': consentString};
+  }
+
+  return o;
+}
+
+registerBidder(spec);
diff --git a/modules/advangelistsBidAdapter.md b/modules/advangelistsBidAdapter.md
new file mode 100644
index 00000000000..14e2befd48f
--- /dev/null
+++ b/modules/advangelistsBidAdapter.md
@@ -0,0 +1,65 @@
+# Overview
+
+```
+Module Name: Advangelists Bidder Adapter
+Module Type: Bidder Adapter
+Maintainer: lokesh@advangelists.com
+```
+
+# Description
+
+Connects to Advangelists exchange for bids.
+
+Advangelists bid adapter supports Banner and Video ads currently.
+
+For more informatio
+
+# Sample Display Ad Unit: For Publishers
+```javascript
+var displayAdUnit = [
+{
+    code: 'display',
+    sizes: [
+        [300, 250],
+        [320, 50]
+    ],
+    bids: [{
+        bidder: 'avng',
+        params: {
+            pubid: '0cf8d6d643e13d86a5b6374148a4afac',
+            placement: 1234
+        }
+    }]
+}];
+```
+
+# Sample Video Ad Unit: For Publishers
+```javascript
+
+var videoAdUnit = {
+	code: 'video',
+	sizes: [320,480],
+	mediaTypes: {
+	  video: {
+	  	playerSize : [[320, 480]], 
+	  	context: 'instream'
+	  }
+	},
+    bids: [
+      {
+      	bidder: 'avng',
+      	params: {
+        	pubid: '8537f00948fc37cc03c5f0f88e198a76',
+        	placement: 1234,
+        	video: {
+            	id: 123,
+            	skip: 1,
+            	mimes : ['video/mp4', 'application/javascript'],
+            	playbackmethod : [2,6],
+            	maxduration: 30
+          	}
+      	}
+      }
+    ]
+  };
+```
\ No newline at end of file
diff --git a/test/spec/advangelistsBidAdapter_spec.js b/test/spec/advangelistsBidAdapter_spec.js
new file mode 100644
index 00000000000..39066cccb30
--- /dev/null
+++ b/test/spec/advangelistsBidAdapter_spec.js
@@ -0,0 +1,141 @@
+import { expect } from 'chai';
+import { spec } from 'modules/advangelistsBidAdapter';
+import { BANNER, VIDEO } from 'src/mediaTypes';
+import * as utils from 'src/utils';
+
+describe('advangelistsBidAdapter', function () {
+  let bidRequests;
+  let bidRequestsVid;
+
+  beforeEach(function () {
+    bidRequests = [{'bidder': 'avng', 'params': {'pubid': '0cf8d6d643e13d86a5b6374148a4afac', 'placement': 1234}, 'crumbs': {'pubcid': '979fde13-c71e-4ac2-98b7-28c90f99b449'}, 'mediaTypes': {'banner': {'sizes': [[300, 250]]}}, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': 'f72931e6-2b0e-4e37-a2bc-1ea912141f81', 'sizes': [[300, 250]], 'bidId': '2aa73f571eaf29', 'bidderRequestId': '1bac84515a7af3', 'auctionId': '5dbc60fa-1aa1-41ce-9092-e6bbd4d478f7', 'src': 'client', 'bidRequestsCount': 1}];
+
+    bidRequestsVid = [{'bidder': 'avng', 'params': {'pubid': '8537f00948fc37cc03c5f0f88e198a76', 'placement': 1234, 'video': {'id': 123, 'skip': 1, 'mimes': ['video/mp4', 'application/javascript'], 'playbackmethod': [2, 6], 'maxduration': 30}}, 'crumbs': {'pubcid': '979fde13-c71e-4ac2-98b7-28c90f99b449'}, 'mediaTypes': {'video': {'playerSize': [[320, 480]], 'context': 'instream'}}, 'adUnitCode': 'video1', 'transactionId': '8b060952-93f7-4863-af44-bb8796b97c42', 'sizes': [], 'bidId': '25c6ab92aa0e81', 'bidderRequestId': '1d420b73a013fc', 'auctionId': '9a69741c-34fb-474c-83e1-cfa003aaee17', 'src': 'client', 'bidRequestsCount': 1}];
+  });
+
+  describe('spec.isBidRequestValid', function () {
+    it('should return true when the required params are passed for banner', function () {
+      const bidRequest = bidRequests[0];
+      expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
+    });
+
+    it('should return true when the required params are passed for video', function () {
+      const bidRequests = bidRequestsVid[0];
+      expect(spec.isBidRequestValid(bidRequests)).to.equal(true);
+    });
+
+    it('should return false when no pub id params are passed', function () {
+      const bidRequest = bidRequests[0];
+      bidRequest.params.pubid = '';
+      expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
+    });
+
+    it('should return false when no placement params are passed', function () {
+      const bidRequest = bidRequests[0];
+      bidRequest.params.placement = '';
+      expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
+    });
+
+    it('should return false when a bid request is not passed', function () {
+      console.log('from spec - no bid request');
+      expect(spec.isBidRequestValid()).to.equal(false);
+      console.log('from spec blank object');
+      expect(spec.isBidRequestValid({})).to.equal(false);
+    });
+  });
+
+  describe('spec.buildRequests', function () {
+    it('should create a POST request for each bid', function () {
+      const bidRequest = bidRequests[0];
+      const requests = spec.buildRequests([ bidRequest ]);
+      expect(requests[0].method).to.equal('POST');
+    });
+
+    it('should create a POST request for each bid in video request', function () {
+      const bidRequest = bidRequestsVid[0];
+      const requests = spec.buildRequests([ bidRequest ]);
+      expect(requests[0].method).to.equal('POST');
+    });
+
+    it('should have domain in request', function () {
+      const bidRequest = bidRequests[0];
+      const requests = spec.buildRequests([ bidRequest ]);
+      expect(Object.keys(requests[0].data.site.domain).length !== 0);
+    });
+  });
+
+  describe('spec.interpretResponse', function () {
+    describe('for banner bids', function () {
+      it('should return no bids if the response is not valid', function () {
+        const bidRequest = bidRequests[0];
+        bidRequest.mediaTypes = { banner: {} };
+        const bidResponse = spec.interpretResponse({ body: null }, { bidRequest });
+
+        if (typeof bidResponse !== 'undefined') {
+          expect(bidResponse.length).to.equal(0);
+        } else {
+          expect(true).to.equal(true);
+        }
+      });
+
+      it('should return no bids if the response is empty', function () {
+        const bidRequest = bidRequests[0];
+        bidRequest.mediaTypes = { banner: {} };
+        const bidResponse = spec.interpretResponse({ body: [] }, { bidRequest });
+        if (typeof bidResponse !== 'undefined') {
+          expect(bidResponse.length).to.equal(0);
+        } else { expect(true).to.equal(true); }
+      });
+
+      it('should return valid video bid responses', function () {
+        let _mediaTypes = VIDEO;
+        const avngbidreqVid = {'bidRequest': {'mediaTypes': {'video': {'w': 320, 'h': 480}}}};
+        const serverResponseVid = {'cur': 'USD', 'id': '25c6ab92aa0e81', 'seatbid': [{'seat': '3', 'bid': [{'crid': '1855', 'h': 480, 'protocol': 2, 'nurl': 'http://nep.advangelists.com/xp/evt?pp=1MO1wiaMhhq7wLRzZZwwwPkJxxKpYEnM5k5MH4qSGm1HR8rp3Nl7vDocvzZzSAvE4pnREL9mQ1kf5PDjk6E8em6DOk7vVrYUH1TYQyqCucd58PFpJNN7h30RXKHHFg3XaLuQ3PKfMuI1qZATBJ6WHcu875y0hqRdiewn0J4JsCYF53M27uwmcV0HnQxARQZZ72mPqrW95U6wgkZljziwKrICM3aBV07TU6YK5R5AyzJRuD6mtrQ2xtHlQ3jXVYKE5bvWFiUQd90t0jOGhPtYBNoOfP7uQ4ZZj4pyucxbr96orHe9PSOn9UpCSWArdx7s8lOfDpwOvbMuyGxynbStDWm38sDgd4bMHnIt762m5VMDNJfiUyX0vWzp05OsufJDVEaWhAM62i40lQZo7mWP4ipoOWLkmlaAzFIMsTcNaHAHiKKqGEOZLkCEhFNM0SLcvgN2HFRULOOIZvusq7TydOKxuXgCS91dLUDxDDDFUK83BFKlMkTxnCzkLbIR1bd9GKcr1TRryOrulyvRWAKAIhEsUzsc5QWFUhmI2dZ1eqnBQJ0c89TaPcnoaP2WipF68UgyiOstf2CBy0M34858tC5PmuQwQYwXscg6zyqDwR0i9MzGH4FkTyU5yeOlPcsA0ht6UcoCdFpHpumDrLUwAaxwGk1Nj8S6YlYYT5wNuTifDGbg22QKXzZBkUARiyVvgPn9nRtXnrd7WmiMYq596rya9RQj7LC0auQW8bHVQLEe49shsZDnAwZTWr4QuYKqgRGZcXteG7RVJe0ryBZezOq11ha9C0Lv0siNVBahOXE35Wzoq4c4BDaGpqvhaKN7pjeWLGlQR04ufWekwxiMWAvjmfgAfexBJ7HfbYNZpq__', 'adid': '61_1855', 'adomain': ['chevrolet.com.ar'], 'price': 2, 'w': 320, 'iurl': 'https://daf37cpxaja7f.cloudfront.net/c61/creative_url_14922301369663_1.png', 'cat': ['IAB2'], 'id': '7f570b40-aca1-4806-8ea8-818ea679c82b_0', 'attr': [], 'impid': '0', 'cid': '61'}]}], 'bidid': '7f570b40-aca1-4806-8ea8-818ea679c82b'}
+        const bidResponseVid = spec.interpretResponse({ body: serverResponseVid }, avngbidreqVid);
+        delete bidResponseVid['vastUrl'];
+        delete bidResponseVid['ad'];
+        // bidResponseVid['mediaType'] = 'video';
+        expect(bidResponseVid).to.deep.equal({
+          requestId: bidRequestsVid[0].bidId,
+          bidderCode: 'avng',
+          creativeId: serverResponseVid.seatbid[0].bid[0].crid,
+          cpm: serverResponseVid.seatbid[0].bid[0].price,
+          width: serverResponseVid.seatbid[0].bid[0].w,
+          height: serverResponseVid.seatbid[0].bid[0].h,
+          mediaType: 'video',
+          currency: 'USD',
+          netRevenue: true,
+          ttl: 60
+        });
+      });
+
+      it('should return valid banner bid responses', function () {
+        const avngbidreq = {bids: {}};
+        bidRequests.forEach(bid => {
+          let _mediaTypes = (bid.mediaTypes && bid.mediaTypes.video ? VIDEO : BANNER);
+          avngbidreq.bids[bid.bidId] = {mediaTypes: _mediaTypes,
+            w: _mediaTypes == BANNER ? bid.mediaTypes[_mediaTypes].sizes[0][0] : bid.mediaTypes[_mediaTypes].playerSize[0],
+            h: _mediaTypes == BANNER ? bid.mediaTypes[_mediaTypes].sizes[0][1] : bid.mediaTypes[_mediaTypes].playerSize[1]
+
+          };
+        });
+        const serverResponse = {'id': '2aa73f571eaf29', 'seatbid': [{'bid': [{'id': '2c5e8a1a84522d', 'impid': '2c5e8a1a84522d', 'price': 0.81, 'adid': 'abcde-12345', 'nurl': '', 'adm': '<div><img src=\'http://cdnin.bnmla.com/0b1c6e85e9376e3092df8c9fc8ab9095.gif\' width=350 height=250 /></div>', 'adomain': ['advertiserdomain.com'], 'iurl': '', 'cid': 'campaign1', 'crid': 'abcde-12345', 'w': 300, 'h': 250}], 'seat': '19513bcfca8006'}], 'bidid': '19513bcfca8006', 'cur': 'USD', 'w': 300, 'h': 250};
+
+        const bidResponse = spec.interpretResponse({ body: serverResponse }, avngbidreq);
+        expect(bidResponse).to.deep.equal({
+          requestId: bidRequests[0].bidId,
+          ad: serverResponse.seatbid[0].bid[0].adm,
+          bidderCode: 'avng',
+          creativeId: serverResponse.seatbid[0].bid[0].crid,
+          cpm: serverResponse.seatbid[0].bid[0].price,
+          width: serverResponse.seatbid[0].bid[0].w,
+          height: serverResponse.seatbid[0].bid[0].h,
+          mediaType: 'banner',
+          currency: 'USD',
+          netRevenue: true,
+          ttl: 60
+        });
+      });
+    });
+  });
+});

From 3ebb9169391a6f5b0d298bc7ee71c85364f9a37c Mon Sep 17 00:00:00 2001
From: Chandra Prakash <chandra.prakash@advangelists.com>
Date: Wed, 27 Feb 2019 13:11:08 -0800
Subject: [PATCH 2/3] Submit Advangelists Prebid Adapter 1.1

---
 test/spec/{ => modules}/advangelistsBidAdapter_spec.js | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
 rename test/spec/{ => modules}/advangelistsBidAdapter_spec.js (95%)

diff --git a/test/spec/advangelistsBidAdapter_spec.js b/test/spec/modules/advangelistsBidAdapter_spec.js
similarity index 95%
rename from test/spec/advangelistsBidAdapter_spec.js
rename to test/spec/modules/advangelistsBidAdapter_spec.js
index 39066cccb30..d75f07f26b8 100644
--- a/test/spec/advangelistsBidAdapter_spec.js
+++ b/test/spec/modules/advangelistsBidAdapter_spec.js
@@ -8,9 +8,9 @@ describe('advangelistsBidAdapter', function () {
   let bidRequestsVid;
 
   beforeEach(function () {
-    bidRequests = [{'bidder': 'avng', 'params': {'pubid': '0cf8d6d643e13d86a5b6374148a4afac', 'placement': 1234}, 'crumbs': {'pubcid': '979fde13-c71e-4ac2-98b7-28c90f99b449'}, 'mediaTypes': {'banner': {'sizes': [[300, 250]]}}, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': 'f72931e6-2b0e-4e37-a2bc-1ea912141f81', 'sizes': [[300, 250]], 'bidId': '2aa73f571eaf29', 'bidderRequestId': '1bac84515a7af3', 'auctionId': '5dbc60fa-1aa1-41ce-9092-e6bbd4d478f7', 'src': 'client', 'bidRequestsCount': 1}];
+    bidRequests = [{'bidder': 'avng', 'params': {'pubid': '0cf8d6d643e13d86a5b6374148a4afac', 'placement': 1234}, 'crumbs': {'pubcid': '979fde13-c71e-4ac2-98b7-28c90f99b449'}, 'mediaTypes': {'banner': {'sizes': [[300, 250]]}}, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': 'f72931e6-2b0e-4e37-a2bc-1ea912141f81', 'sizes': [[300, 250]], 'bidId': '2aa73f571eaf29', 'bidderRequestId': '1bac84515a7af3', 'auctionId': '5dbc60fa-1aa1-41ce-9092-e6bbd4d478f7', 'src': 'client', 'bidRequestsCount': 1, 'pageurl': 'http://google.com'}];
 
-    bidRequestsVid = [{'bidder': 'avng', 'params': {'pubid': '8537f00948fc37cc03c5f0f88e198a76', 'placement': 1234, 'video': {'id': 123, 'skip': 1, 'mimes': ['video/mp4', 'application/javascript'], 'playbackmethod': [2, 6], 'maxduration': 30}}, 'crumbs': {'pubcid': '979fde13-c71e-4ac2-98b7-28c90f99b449'}, 'mediaTypes': {'video': {'playerSize': [[320, 480]], 'context': 'instream'}}, 'adUnitCode': 'video1', 'transactionId': '8b060952-93f7-4863-af44-bb8796b97c42', 'sizes': [], 'bidId': '25c6ab92aa0e81', 'bidderRequestId': '1d420b73a013fc', 'auctionId': '9a69741c-34fb-474c-83e1-cfa003aaee17', 'src': 'client', 'bidRequestsCount': 1}];
+    bidRequestsVid = [{'bidder': 'avng', 'params': {'pubid': '8537f00948fc37cc03c5f0f88e198a76', 'placement': 1234, 'video': {'id': 123, 'skip': 1, 'mimes': ['video/mp4', 'application/javascript'], 'playbackmethod': [2, 6], 'maxduration': 30}}, 'crumbs': {'pubcid': '979fde13-c71e-4ac2-98b7-28c90f99b449'}, 'mediaTypes': {'video': {'playerSize': [[320, 480]], 'context': 'instream'}}, 'adUnitCode': 'video1', 'transactionId': '8b060952-93f7-4863-af44-bb8796b97c42', 'sizes': [], 'bidId': '25c6ab92aa0e81', 'bidderRequestId': '1d420b73a013fc', 'auctionId': '9a69741c-34fb-474c-83e1-cfa003aaee17', 'src': 'client', 'bidRequestsCount': 1, 'pageurl': 'http://google.com'}];
   });
 
   describe('spec.isBidRequestValid', function () {
@@ -60,7 +60,9 @@ describe('advangelistsBidAdapter', function () {
     it('should have domain in request', function () {
       const bidRequest = bidRequests[0];
       const requests = spec.buildRequests([ bidRequest ]);
-      expect(Object.keys(requests[0].data.site.domain).length !== 0);
+      console.log(requests[0].data.site.domain);
+      // expect(Object.keys(requests[0].data.site.domain).length !== 0);
+      expect(requests[0].data.site.domain).length !== 0;
     });
   });
 

From 3aa135aee4304b834c8c1ea8c0267b31d327acd3 Mon Sep 17 00:00:00 2001
From: Chandra Prakash <chandra.prakash@advangelists.com>
Date: Thu, 28 Feb 2019 14:39:15 -0800
Subject: [PATCH 3/3] Submit Advangelists Prebid Adapter Changes

---
 modules/advangelistsBidAdapter.js             | 72 ++-----------------
 .../modules/advangelistsBidAdapter_spec.js    |  6 --
 2 files changed, 4 insertions(+), 74 deletions(-)

diff --git a/modules/advangelistsBidAdapter.js b/modules/advangelistsBidAdapter.js
index d0298db4e1c..926be211649 100644
--- a/modules/advangelistsBidAdapter.js
+++ b/modules/advangelistsBidAdapter.js
@@ -2,19 +2,16 @@ import * as utils from '../src/utils';
 import { parse as parseUrl } from '../src/url';
 import { config } from '../src/config';
 import { registerBidder } from '../src/adapters/bidderFactory';
-// import { Renderer } from '../src/Renderer';
 import { VIDEO, BANNER } from '../src/mediaTypes';
 import find from 'core-js/library/fn/array/find';
 import includes from 'core-js/library/fn/array/includes';
 
 const ADAPTER_VERSION = '1.0';
 const BIDDER_CODE = 'avng';
-// const OUTSTREAM = 'outstream';
 
 export const VIDEO_ENDPOINT = '//nep.advangelists.com/xp/get?pubid=';// 0cf8d6d643e13d86a5b6374148a4afac';
 export const BANNER_ENDPOINT = '//nep.advangelists.com/xp/get?pubid=';// 0cf8d6d643e13d86a5b6374148a4afac';
 export const OUTSTREAM_SRC = '//player-cdn.beachfrontmedia.com/playerapi/loader/outstream.js';
-
 export const VIDEO_TARGETING = ['mimes', 'playbackmethod', 'maxduration', 'skip'];
 export const DEFAULT_MIMES = ['video/mp4', 'application/javascript'];
 
@@ -55,8 +52,6 @@ export const spec = {
         bidRequest: bid
       });
     });
-
-    console.log(requests);
     return requests;
   },
 
@@ -64,7 +59,6 @@ export const spec = {
     let response = serverResponse.body;
     if (response !== null && utils.isEmpty(response) == false) {
       if (isVideoBid(bidRequest)) {
-        console.log('About to create final response for video')
         let bidResponse = {
           requestId: response.id,
           bidderCode: BIDDER_CODE,
@@ -89,7 +83,6 @@ export const spec = {
 
         return bidResponse;
       } else {
-        console.log('About to create final respsone for banner')
         return {
           requestId: response.id,
           bidderCode: BIDDER_CODE,
@@ -106,38 +99,6 @@ export const spec = {
       }
     }
   }
-/*,
-
-  getUserSyncs(syncOptions, serverResponses = [], gdprConsent = {}) {
-    let syncs = [];
-    let { gdprApplies, consentString } = gdprConsent;
-    let bannerResponse = find(serverResponses, (res) => utils.isArray(res.body));
-
-    if (bannerResponse) {
-      if (syncOptions.iframeEnabled) {
-        bannerResponse.body
-          .filter(bid => bid.sync)
-          .forEach(bid => {
-            syncs.push({
-              type: 'iframe',
-              url: bid.sync
-            });
-          });
-      }
-    } else if (syncOptions.iframeEnabled) {
-      syncs.push({
-        type: 'iframe',
-        url: `//sync.bfmio.com/sync_iframe?ifg=1&id=${appId}&gdpr=${gdprApplies ? 1 : 0}&gc=${consentString || ''}&gce=1`
-      });
-    } else if (syncOptions.pixelEnabled) {
-      syncs.push({
-        type: 'image',
-        url: `//sync.bfmio.com/syncb?pid=144&id=${appId}&gdpr=${gdprApplies ? 1 : 0}&gc=${consentString || ''}&gce=1`
-      });
-    }
-
-    return syncs;
-  } */
 };
 
 function isBannerBid(bid) {
@@ -186,31 +147,6 @@ function findAndFillParam(o, key, value) {
   } catch (ex) {}
 }
 
-/*
-function createRenderer(bidRequest) {
-  const renderer = Renderer.install({
-    id: bidRequest.bidId,
-    url: OUTSTREAM_SRC,
-    loaded: false
-  });
-
-  renderer.setRender(outstreamRender);
-
-  return renderer;
-}
-
-function outstreamRender(bid) {
-  bid.renderer.push(() => {
-    window.Beachfront.Player(bid.adUnitCode, {
-      ad_tag_url: bid.vastUrl,
-      width: bid.width,
-      height: bid.height,
-      expand_in_view: false,
-      collapse_on_complete: true
-    });
-  });
-}
-*/
 function getOsVersion() {
   let clientStrings = [
     { s: 'Android', r: /Android/ },
@@ -279,7 +215,7 @@ function createVideoRequestData(bid, bidderRequest) {
   let firstSize = getFirstSize(sizes);
 
   let video = getVideoTargetingParams(bid);
-  var o = {
+  const o = {
     'device': {
       'langauge': (global.navigator.language).split('-')[0],
       'dnt': (global.navigator.doNotTrack === 1 ? 1 : 0),
@@ -309,7 +245,7 @@ function createVideoRequestData(bid, bidderRequest) {
   o.site['domain'] = topLocation.hostname;
   o.site['ref'] = topReferrer;
   o.site['mobile'] = isMobile() ? 1 : 0;
-  var secure = topLocation.protocol.indexOf('https') === 0 ? 1 : 0;
+  const secure = topLocation.protocol.indexOf('https') === 0 ? 1 : 0;
 
   o.device['dnt'] = getDoNotTrack() ? 1 : 0;
 
@@ -366,7 +302,7 @@ function createBannerRequestData(bid, bidderRequest) {
 
   let sizes = getBannerSizes(bid);
 
-  var o = {
+  const o = {
     'device': {
       'langauge': (global.navigator.language).split('-')[0],
       'dnt': (global.navigator.doNotTrack === 1 ? 1 : 0),
@@ -395,7 +331,7 @@ function createBannerRequestData(bid, bidderRequest) {
   o.site['domain'] = topLocation.hostname;
   o.site['ref'] = topReferrer;
   o.site['mobile'] = isMobile() ? 1 : 0;
-  var secure = topLocation.protocol.indexOf('https') === 0 ? 1 : 0;
+  const secure = topLocation.protocol.indexOf('https') === 0 ? 1 : 0;
 
   o.device['dnt'] = getDoNotTrack() ? 1 : 0;
 
diff --git a/test/spec/modules/advangelistsBidAdapter_spec.js b/test/spec/modules/advangelistsBidAdapter_spec.js
index d75f07f26b8..f7a49ef995f 100644
--- a/test/spec/modules/advangelistsBidAdapter_spec.js
+++ b/test/spec/modules/advangelistsBidAdapter_spec.js
@@ -1,7 +1,6 @@
 import { expect } from 'chai';
 import { spec } from 'modules/advangelistsBidAdapter';
 import { BANNER, VIDEO } from 'src/mediaTypes';
-import * as utils from 'src/utils';
 
 describe('advangelistsBidAdapter', function () {
   let bidRequests;
@@ -37,9 +36,7 @@ describe('advangelistsBidAdapter', function () {
     });
 
     it('should return false when a bid request is not passed', function () {
-      console.log('from spec - no bid request');
       expect(spec.isBidRequestValid()).to.equal(false);
-      console.log('from spec blank object');
       expect(spec.isBidRequestValid({})).to.equal(false);
     });
   });
@@ -60,8 +57,6 @@ describe('advangelistsBidAdapter', function () {
     it('should have domain in request', function () {
       const bidRequest = bidRequests[0];
       const requests = spec.buildRequests([ bidRequest ]);
-      console.log(requests[0].data.site.domain);
-      // expect(Object.keys(requests[0].data.site.domain).length !== 0);
       expect(requests[0].data.site.domain).length !== 0;
     });
   });
@@ -96,7 +91,6 @@ describe('advangelistsBidAdapter', function () {
         const bidResponseVid = spec.interpretResponse({ body: serverResponseVid }, avngbidreqVid);
         delete bidResponseVid['vastUrl'];
         delete bidResponseVid['ad'];
-        // bidResponseVid['mediaType'] = 'video';
         expect(bidResponseVid).to.deep.equal({
           requestId: bidRequestsVid[0].bidId,
           bidderCode: 'avng',