Beispiel #1
0
    it('returns false when a required property from an adpod bid is missing', function() {
      function testInvalidAdpodBid(badTestBid, shouldErrorBeLogged) {
        checkVideoBidSetupHook(callbackFn, badTestBid, bidderRequestNoExact, {}, ADPOD);
        expect(callbackResult).to.be.null;
        expect(bailResult).to.equal(false);
        expect(logErrorStub.called).to.equal(shouldErrorBeLogged);
      }

      let noCatBid = utils.deepClone(adpodTestBid);
      noCatBid.meta.iabSubCatId = undefined;
      testInvalidAdpodBid(noCatBid, false);

      let noContextBid = utils.deepClone(adpodTestBid);
      delete noContextBid.video.context;
      testInvalidAdpodBid(noContextBid, false);

      let wrongContextBid = utils.deepClone(adpodTestBid);
      wrongContextBid.video.context = 'instream';
      testInvalidAdpodBid(wrongContextBid, false);

      let noDurationBid = utils.deepClone(adpodTestBid);
      delete noDurationBid.video.durationSeconds;
      testInvalidAdpodBid(noDurationBid, false);

      config.resetConfig();
      let noCacheUrlBid = utils.deepClone(adpodTestBid);
      testInvalidAdpodBid(noCacheUrlBid, true);
    });
      it('adds gdpr consent information to ortb2 request depending on presence of module', () => {
        let ortb2Config = utils.deepClone(CONFIG);
        ortb2Config.endpoint = 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'

        let consentConfig = { consentManagement: { cmpApi: 'iab' }, s2sConfig: ortb2Config };
        config.setConfig(consentConfig);

        let gdprBidRequest = utils.deepClone(BID_REQUESTS);
        gdprBidRequest[0].gdprConsent = {
          consentString: 'abc123',
          gdprApplies: true
        };

        adapter.callBids(REQUEST, gdprBidRequest, addBidResponse, done, ajax);
        let requestBid = JSON.parse(requests[0].requestBody);

        expect(requestBid.regs.ext.gdpr).is.equal(1);
        expect(requestBid.user.ext.consent).is.equal('abc123');

        config.resetConfig();
        config.setConfig({s2sConfig: CONFIG});

        adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
        requestBid = JSON.parse(requests[1].requestBody);

        expect(requestBid.regs).to.not.exist;
        expect(requestBid.user).to.not.exist;
      });
Beispiel #3
0
      it('when requireExactDuration is false and bids are bucketed properly', function() {
        function testRoundingForGoodBId(bid, bucketValue) {
          checkVideoBidSetupHook(callbackFn, bid, bidderRequestNoExact, {}, ADPOD);
          expect(callbackResult).to.be.null;
          expect(bid.video.durationBucket).to.equal(bucketValue);
          expect(bailResult).to.equal(true);
          expect(logWarnStub.called).to.equal(false);
        }

        let goodBid45 = utils.deepClone(basicBid);
        goodBid45.video.durationSeconds = 45;
        testRoundingForGoodBId(goodBid45, 45);

        let goodBid30 = utils.deepClone(basicBid);
        goodBid30.video.durationSeconds = 30;
        testRoundingForGoodBId(goodBid30, 45);

        let goodBid10 = utils.deepClone(basicBid);
        goodBid10.video.durationSeconds = 10;
        testRoundingForGoodBId(goodBid10, 15);

        let goodBid16 = utils.deepClone(basicBid);
        goodBid16.video.durationSeconds = 16;
        testRoundingForGoodBId(goodBid16, 15);

        let goodBid47 = utils.deepClone(basicBid);
        goodBid47.video.durationSeconds = 47;
        testRoundingForGoodBId(goodBid47, 45);
      });
    it('should include all adserver targeting in cust_params if pbjs.enableSendAllBids is true', function () {
      const adUnitsCopy = utils.deepClone(adUnit);
      adUnitsCopy.bids.push({
        'bidder': 'testBidder2',
        'params': {
          'placementId': '9333431',
          'video': {
            'skipppable': false,
            'playback_methods': ['auto_play_sound_off']
          }
        }
      });

      const bidCopy = utils.deepClone(bid);
      bidCopy.adserverTargeting = Object.assign(bidCopy.adserverTargeting, {
        hb_adid: 'ad_id',
      });

      const url = parse(buildDfpVideoUrl({
        adUnit: adUnitsCopy,
        bid: bidCopy,
        params: {
          'iu': 'my/adUnit'
        }
      }));
      const queryObject = parseQS(url.query);
      const customParams = parseQS('?' + decodeURIComponent(queryObject.cust_params));

      expect(customParams).to.have.property('hb_adid', 'ad_id');
      expect(customParams).to.have.property('hb_uuid', bid.videoCacheKey);
      expect(customParams).to.have.property('hb_cache_id', bid.videoCacheKey);
      expect(customParams).to.have.property('hb_bidder_appnexus', 'appnexus');
      expect(customParams).to.have.property('hb_bidder_testBidder2', 'testBidder2');
    });
    it('builds request correctly', () => {
      let stub = sinon.stub(utils, 'getTopWindowUrl').returns('http://www.test.com/page.html');

      let response;
      response = spec.buildRequests([bidRequest])[0];
      expect(response.data.site.domain).to.equal('www.test.com');
      expect(response.data.site.page).to.equal('http://www.test.com/page.html');
      expect(response.data.site.ref).to.equal('');
      expect(response.data.imp.length).to.equal(1);
      expect(response.data.imp[0].id).to.equal(bidRequest.transactionId);
      expect(response.data.imp[0].instl).to.equal(0);
      expect(response.data.imp[0].tagid).to.equal(bidRequest.adUnitCode);
      expect(response.data.imp[0].bidfloor).to.equal(0);
      expect(response.data.imp[0].bidfloorcur).to.equal('USD');

      const bidRequestWithInstlEquals1 = utils.deepClone(bidRequest);
      bidRequestWithInstlEquals1.params.instl = 1;
      response = spec.buildRequests([bidRequestWithInstlEquals1])[0];
      expect(response.data.imp[0].instl).to.equal(bidRequestWithInstlEquals1.params.instl);

      const bidRequestWithInstlEquals0 = utils.deepClone(bidRequest);
      bidRequestWithInstlEquals0.params.instl = 1;
      response = spec.buildRequests([bidRequestWithInstlEquals0])[0];
      expect(response.data.imp[0].instl).to.equal(bidRequestWithInstlEquals0.params.instl);

      const bidRequestWithBidfloorEquals1 = utils.deepClone(bidRequest);
      bidRequestWithBidfloorEquals1.params.bidfloor = 1;
      response = spec.buildRequests([bidRequestWithBidfloorEquals1])[0];
      expect(response.data.imp[0].bidfloor).to.equal(bidRequestWithBidfloorEquals1.params.bidfloor);

      stub.restore();
    });
    it('should be false because the env is missing or wrong', function () {
      let wrongBid = utils.deepClone(bid);
      wrongBid.params.env = 'us';
      expect(adapter.isBidRequestValid(wrongBid)).to.be.false;

      wrongBid = utils.deepClone(bid);
      delete wrongBid.params.env;
      expect(adapter.isBidRequestValid(wrongBid)).to.be.false;
    });
    it('should be empty because the body is missing or wrong', function () {
      let wrongResponse = utils.deepClone(response);
      wrongResponse.body = [1, 2, 3];
      expect(adapter.interpretResponse(wrongResponse, bid)).to.be.empty;

      wrongResponse = utils.deepClone(response);
      delete wrongResponse.body;
      expect(adapter.interpretResponse(wrongResponse, bid)).to.be.empty;
    });
    it('should be false because the sizes are missing or in the wrong format', function () {
      let wrongBid = utils.deepClone(bid);
      wrongBid.sizes = '640360';
      expect(adapter.isBidRequestValid(wrongBid)).to.be.false;

      wrongBid = utils.deepClone(bid);
      delete wrongBid.sizes;
      expect(adapter.isBidRequestValid(wrongBid)).to.be.false;
    });
    it('should be false because the mediaType is missing or wrong', function () {
      let wrongBid = utils.deepClone(bid);
      wrongBid.mediaTypes = {};
      expect(adapter.isBidRequestValid(wrongBid)).to.be.false;

      wrongBid = utils.deepClone(bid);
      delete wrongBid.mediaTypes;
      expect(adapter.isBidRequestValid(wrongBid)).to.be.false;
    });
    it('converts appnexus params to expected format for PBS', () => {
      const s2sConfig = Object.assign({}, CONFIG, {
        endpoint: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'
      });
      config.setConfig({s2sConfig: s2sConfig});

      const myRequest = utils.deepClone(REQUEST);
      myRequest.ad_units[0].bids[0].params.usePaymentRule = true;
      myRequest.ad_units[0].bids[0].params.keywords = {
        foo: ['bar', 'baz'],
        fizz: ['buzz']
      };

      adapter.callBids(myRequest, BID_REQUESTS, addBidResponse, done, ajax);
      const requestBid = JSON.parse(requests[0].requestBody);

      expect(requestBid.imp[0].ext.appnexus).to.exist;
      expect(requestBid.imp[0].ext.appnexus.placement_id).to.exist.and.to.equal(10433394);
      expect(requestBid.imp[0].ext.appnexus.use_pmt_rule).to.exist.and.to.be.true;
      expect(requestBid.imp[0].ext.appnexus.member).to.exist;
      expect(requestBid.imp[0].ext.appnexus.keywords).to.exist.and.to.deep.equal([{
        key: 'foo',
        value: ['bar', 'baz']
      }, {
        key: 'fizz',
        value: ['buzz']
      }]);

      config.resetConfig();
      const oldS2sConfig = Object.assign({}, CONFIG);
      config.setConfig({s2sConfig: oldS2sConfig});

      const myRequest2 = utils.deepClone(REQUEST);
      myRequest2.ad_units[0].bids[0].params.keywords = {
        foo: ['bar', 'baz'],
        fizz: ['buzz']
      };

      adapter.callBids(myRequest2, BID_REQUESTS, addBidResponse, done, ajax);
      const requestBid2 = JSON.parse(requests[1].requestBody);

      expect(requestBid2.ad_units[0].bids[0].params.keywords).to.exist.and.to.deep.equal([{
        key: 'foo',
        value: ['bar', 'baz']
      }, {
        key: 'fizz',
        value: ['buzz']
      }]);
    });
Beispiel #11
0
  baseAdapter.callBids = function(s2sBidRequest, bidRequests, addBidResponse, done, ajax) {
    const adUnits = utils.deepClone(s2sBidRequest.ad_units);

    // at this point ad units should have a size array either directly or mapped so filter for that
    const adUnitsWithSizes = adUnits.filter(unit => unit.sizes && unit.sizes.length);

    // in case config.bidders contains invalid bidders, we only process those we sent requests for
    const requestedBidders = adUnitsWithSizes
      .map(adUnit => adUnit.bids.map(bid => bid.bidder).filter(utils.uniques))
      .reduce(utils.flatten)
      .filter(utils.uniques);

    if (_s2sConfig && _s2sConfig.syncEndpoint) {
      let consent = (Array.isArray(bidRequests) && bidRequests.length > 0) ? bidRequests[0].gdprConsent : undefined;
      queueSync(_s2sConfig.bidders, consent);
    }

    const request = protocolAdapter().buildRequest(s2sBidRequest, bidRequests, adUnitsWithSizes);
    const requestJson = JSON.stringify(request);

    ajax(
      _s2sConfig.endpoint,
      {
        success: response => handleResponse(response, requestedBidders, bidRequests, addBidResponse, done),
        error: done
      },
      requestJson,
      { contentType: 'text/plain', withCredentials: true }
    );
  };
 it('builds with bid floor', function() {
   const bidRequestWithBidFloor = utils.deepClone(bidRequests);
   bidRequestWithBidFloor[0].params.bidfloor = 1;
   const requestWithFloor = spec.buildRequests(bidRequestWithBidFloor, bidderRequest);
   const data = JSON.parse(requestWithFloor.data);
   expect(data.imp[0].bidfloor).to.equal(bidRequestWithBidFloor[0].params.bidfloor);
 })
Beispiel #13
0
    it('Valid bid request - sizes old style - no media type', function () {
      let bidsClone = utils.deepClone(bids);
      delete (bidsClone[0].mediaTypes);
      delete (bidsClone[1]);

      let imps = [
        {
          banner: {
            format: [
              {
                w: 300,
                h: 250
              }
            ]
          },
          ext: {
            pid: 607
          },
          id: '2e56e1af51a5d7',
          secure: 1
        }
      ];

      let response = spec.buildRequests(bidsClone, {'bids': bidsClone});
      let data = JSON.parse(response.data);

      expect(data.imp).to.deep.have.same.members(imps);
    });
Beispiel #14
0
 it('returns true when adpod bid is missing iab category while brandCategoryExclusion in config is false', function() {
   let goodBid = utils.deepClone(adpodTestBid);
   checkVideoBidSetupHook(callbackFn, goodBid, bidderRequestNoExact, {}, ADPOD);
   expect(callbackResult).to.be.null;
   expect(bailResult).to.equal(true);
   expect(logErrorStub.called).to.equal(false);
 });
 it('should return false when mediaType is native', function () {
   const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]);
   delete bid.params.mediaTypes;
   bid.mediaType = 'native';
   bid.sizes = [[300, 250]];
   expect(spec.isBidRequestValid(bid)).to.equal(false);
 });
    it('handles native responses', () => {
      let response1 = deepClone(response);
      response1.tags[0].ads[0].ad_type = 'native';
      response1.tags[0].ads[0].rtb.native = {
        'title': 'Native Creative',
        'desc': 'Cool description great stuff',
        'ctatext': 'Do it',
        'sponsored': 'AppNexus',
        'icon': {
          'width': 0,
          'height': 0,
          'url': 'http://cdn.adnxs.com/icon.png'
        },
        'main_img': {
          'width': 2352,
          'height': 1516,
          'url': 'http://cdn.adnxs.com/img.png'
        },
        'link': {
          'url': 'https://www.appnexus.com',
          'fallback_url': '',
          'click_trackers': ['http://nym1-ib.adnxs.com/click']
        },
        'impression_trackers': ['http://example.com'],
      };
      let bidderRequest;

      let result = spec.interpretResponse({ body: response1 }, {bidderRequest});
      expect(result[0].native.title).to.equal('Native Creative');
      expect(result[0].native.body).to.equal('Cool description great stuff');
      expect(result[0].native.cta).to.equal('Do it');
      expect(result[0].native.image.url).to.equal('http://cdn.adnxs.com/img.png');
    });
 it('should return true when mediaType is banner', function () {
   const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]);
   delete bid.mediaTypes;
   bid.mediaType = 'banner';
   bid.sizes = [[300, 250]];
   expect(spec.isBidRequestValid(bid)).to.equal(true);
 });
Beispiel #18
0
 it('Invalid bid reqeusts - invalid video sizes', function () {
   let bidsClone = utils.deepClone(bids);
   bidsClone[1].mediaTypes.video.playerSize = [];
   expect(spec.isBidRequestValid(bidsClone[1])).to.be.false;
   bidsClone[1].mediaTypes.video.sizes = [640, 480];
   expect(spec.isBidRequestValid(bidsClone[1])).to.be.false;
 });
 it('should set dealId correctly', function () {
   const bidResponse = utils.deepClone(DEFAULT_BANNER_BID_RESPONSE);
   bidResponse.seatbid[0].bid[0].ext.dealid = 'deal';
   const expectedParse = [
     {
       requestId: '1a2b3c4d',
       cpm: 1,
       creativeId: '12345',
       width: 300,
       height: 250,
       ad: '<a target="_blank" href="http://www.indexexchange.com"></a>',
       currency: 'USD',
       ttl: 35,
       netRevenue: true,
       dealId: 'deal',
       meta: {
         networkId: 50,
         brandId: 303325,
         brandName: 'OECTA'
       }
     }
   ];
   const result = spec.interpretResponse({ body: bidResponse });
   expect(result[0]).to.deep.equal(expectedParse[0]);
 });
    it('adds appnexus aliases to request', () => {
      const s2sConfig = Object.assign({}, CONFIG, {
        endpoint: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'
      });
      config.setConfig({s2sConfig: s2sConfig});

      const aliasBidder = {
        bidder: 'brealtime',
        params: { placementId: '123456' }
      };

      const request = utils.deepClone(REQUEST);
      request.ad_units[0].bids = [aliasBidder];

      adapter.callBids(request, BID_REQUESTS, addBidResponse, done, ajax);

      const requestBid = JSON.parse(requests[0].requestBody);

      expect(requestBid.ext).to.deep.equal({
        prebid: {
          aliases: {
            brealtime: 'appnexus'
          }
        }
      });
    });
    it('adds dynamic aliases to request', () => {
      const s2sConfig = Object.assign({}, CONFIG, {
        endpoint: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'
      });
      config.setConfig({s2sConfig: s2sConfig});

      const alias = 'foobar';
      const aliasBidder = {
        bidder: alias,
        params: { placementId: '123456' }
      };

      const request = utils.deepClone(REQUEST);
      request.ad_units[0].bids = [aliasBidder];

      // TODO: stub this
      $$PREBID_GLOBAL$$.aliasBidder('appnexus', alias);
      adapter.callBids(request, BID_REQUESTS, addBidResponse, done, ajax);

      const requestBid = JSON.parse(requests[0].requestBody);

      expect(requestBid.ext).to.deep.equal({
        prebid: {
          aliases: {
            [alias]: 'appnexus'
          }
        }
      });
    });
 it('should take default TTL', () => {
   const serverResponse = utils.deepClone(SERVER_RESPONSE);
   delete serverResponse.body.exp;
   const responses = adapter.interpretResponse(serverResponse, REQUEST);
   expect(responses).to.have.length(1);
   expect(responses[0].ttl).to.equal(300);
 });
    it('returns an array', () => {
      let response;

      response = spec.buildRequests([]);
      expect(Array.isArray(response)).to.equal(true);
      expect(response.length).to.equal(0);

      response = spec.buildRequests([bidRequest]);
      expect(Array.isArray(response)).to.equal(true);
      expect(response.length).to.equal(1);

      const adUnit1 = Object.assign({}, utils.deepClone(bidRequest), {auctionId: '1', adUnitCode: 'a'});
      const adUnit2 = Object.assign({}, utils.deepClone(bidRequest), {auctionId: '1', adUnitCode: 'b'});
      response = spec.buildRequests([adUnit1, adUnit2]);
      expect(Array.isArray(response)).to.equal(true);
      expect(response.length).to.equal(2);
    });
Beispiel #24
0
      it('when requireExactDuration is false and bid duration exceeds listed buckets', function() {
        function testRoundingForBadBid(bid) {
          checkVideoBidSetupHook(callbackFn, bid, bidderRequestNoExact, {}, ADPOD);
          expect(callbackResult).to.be.null;
          expect(bid.video.durationBucket).to.be.undefined;
          expect(bailResult).to.equal(false);
          expect(logWarnStub.called).to.equal(true);
        }

        let badBid100 = utils.deepClone(basicBid);
        badBid100.video.durationSeconds = 100;
        testRoundingForBadBid(badBid100);

        let badBid48 = utils.deepClone(basicBid);
        badBid48.video.durationSeconds = 48;
        testRoundingForBadBid(badBid48);
      });
Beispiel #25
0
      beforeEach(function() {
        bid4 = utils.deepClone(bid1);
        bid4.adserverTargeting['hb_bidder'] = bid4.bidder = bid4.bidderCode = 'appnexus';
        bid4.cpm = 0;
        enableSendAllBids = true;

        bidsReceived.push(bid4);
      });
Beispiel #26
0
      it('when requireExactDuration is true', function() {
        let goodBid = utils.deepClone(basicBid);
        checkVideoBidSetupHook(callbackFn, goodBid, bidderRequestWithExact, {}, ADPOD);

        expect(callbackResult).to.be.null;
        expect(goodBid.video.durationBucket).to.equal(30);
        expect(bailResult).to.equal(true);
        expect(logWarnStub.called).to.equal(false);

        let badBid = utils.deepClone(basicBid);
        badBid.video.durationSeconds = 14;
        checkVideoBidSetupHook(callbackFn, badBid, bidderRequestWithExact, {}, ADPOD);

        expect(callbackResult).to.be.null;
        expect(badBid.video.durationBucket).to.be.undefined;
        expect(bailResult).to.equal(false);
        expect(logWarnStub.calledOnce).to.equal(true);
      });
Beispiel #27
0
 it('Invalid bid reqeusts - invalid banner sizes', function () {
   let bidsClone = utils.deepClone(bids);
   bidsClone[0].mediaTypes.banner.sizes = [300, 250];
   expect(spec.isBidRequestValid(bidsClone[0])).to.be.false;
   bidsClone[0].mediaTypes.banner.sizes = [[300, 250], [750]];
   expect(spec.isBidRequestValid(bidsClone[0])).to.be.false;
   bidsClone[0].mediaTypes.banner.sizes = [];
   expect(spec.isBidRequestValid(bidsClone[0])).to.be.false;
 });
 it('should return false when size array is wrong length', function () {
   const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]);
   bid.params.size = [
     300,
     250,
     250
   ];
   expect(spec.isBidRequestValid(bid)).to.equal(false);
 });
Beispiel #29
0
 it('Valid bid reqeust - old style sizes', function () {
   let bidsClone = utils.deepClone(bids);
   delete (bidsClone[0].mediaTypes);
   delete (bidsClone[1].mediaTypes);
   expect(spec.isBidRequestValid(bidsClone[0])).to.be.true;
   expect(spec.isBidRequestValid(bidsClone[1])).to.be.true;
   bidsClone[0].sizes = [300, 250];
   expect(spec.isBidRequestValid(bidsClone[0])).to.be.true;
 });
 it('should return false when mediaTypes.banner does not have sizes', function () {
   const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]);
   bid.mediaTypes = {
     banner: {
       size: [[300, 250]]
     }
   };
   expect(spec.isBidRequestValid(bid)).to.equal(false);
 });