text: import { expect } from 'chai';
  import { spec } from 'modules/xhbBidAdapter';
  import { newBidder } from 'src/adapters/bidderFactory';
  import { deepClone } from 'src/utils';
  
  const ENDPOINT = '//ib.adnxs.com/ut/v3/prebid';
  
  describe('xhbAdapter', function () {
    const adapter = newBidder(spec);
  
    describe('inherited functions', function () {
      it('exists and is a function', function () {
        expect(adapter.callBids).to.exist.and.to.be.a('function');
      });
    });
  
    describe('isBidRequestValid', function () {
      let bid = {
        'bidder': 'xhb',
        'params': {
          'placementId': '10433394'
        },
        'adUnitCode': 'adunit-code',
        'sizes': [[300, 250], [300, 600]],
        'bidId': '30b31c1838de1e',
        'bidderRequestId': '22edbae2733bf6',
        'auctionId': '1d1a030790a475',
      };
  
      it('should return true when required params found', function () {
        expect(spec.isBidRequestValid(bid)).to.equal(true);
      });
  
      it('should return true when required params found', function () {
        let bid = Object.assign({}, bid);
        delete bid.params;
        bid.params = {
          'member': '1234',
          'invCode': 'ABCD'
        };
  
        expect(spec.isBidRequestValid(bid)).to.equal(true);
      });
  
      it('should return false when required params are not passed', function () {
        let bid = Object.assign({}, bid);
        delete bid.params;
        bid.params = {
          'placementId': 0
        };
        expect(spec.isBidRequestValid(bid)).to.equal(false);
      });
    });
  
    describe('buildRequests', function () {
      let bidRequests = [
        {
          'bidder': 'xhb',
          'params': {
            'placementId': '10433394'
          },
          'adUnitCode': 'adunit-code',
          'sizes': [[300, 250], [300, 600]],
          'bidId': '30b31c1838de1e',
          'bidderRequestId': '22edbae2733bf6',
          'auctionId': '1d1a030790a475',
        }
      ];
  
      it('should parse out private sizes', function () {
        let bidRequest = Object.assign({},
          bidRequests[0],
          {
            params: {
              placementId: '10433394',
              privateSizes: [300, 250]
            }
          }
        );
  
        const request = spec.buildRequests([bidRequest]);
        const payload = JSON.parse(request.data);
  
        expect(payload.tags[0].private_sizes).to.exist;
        expect(payload.tags[0].private_sizes).to.deep.equal([{width: 300, height: 250}]);
      });
  
      it('should add source and verison to the tag', function () {
        const request = spec.buildRequests(bidRequests);
        const payload = JSON.parse(request.data);
        expect(payload.sdk).to.exist;
        expect(payload.sdk).to.deep.equal({
          source: 'pbjs',
          version: '$prebid.version$'
        });
      });
  
      it('should populate the ad_types array on all requests', function () {
        ['banner', 'video', 'native'].forEach(type => {
          const bidRequest = Object.assign({}, bidRequests[0]);
          bidRequest.mediaTypes = {};
          bidRequest.mediaTypes[type] = {};
  
          const request = spec.buildRequests([bidRequest]);
          const payload = JSON.parse(request.data);
  
          expect(payload.tags[0].ad_types).to.deep.equal([type]);
        });
      });
  
      it('should populate the ad_types array on outstream requests', function () {
        const bidRequest = Object.assign({}, bidRequests[0]);
        bidRequest.mediaTypes = {};
        bidRequest.mediaTypes.video = {context: 'outstream'};
  
        const request = spec.buildRequests([bidRequest]);
        const payload = JSON.parse(request.data);
  
        expect(payload.tags[0].ad_types).to.deep.equal(['video']);
      });
  
      it('sends bid request to ENDPOINT via POST', function () {
        const request = spec.buildRequests(bidRequests);
        expect(request.url).to.equal(ENDPOINT);
        expect(request.method).to.equal('POST');
      });
  
      it('should attach valid video params to the tag', function () {
        let bidRequest = Object.assign({},
          bidRequests[0],
          {
            params: {
              placementId: '10433394',
              video: {
                id: 123,
                minduration: 100,
                foobar: 'invalid'
              }
            }
          }
        );
  
        const request = spec.buildRequests([bidRequest]);
        const payload = JSON.parse(request.data);
        expect(payload.tags[0].video).to.deep.equal({
          id: 123,
          minduration: 100
        });
      });
  
      it('should attach valid user params to the tag', function () {
        let bidRequest = Object.assign({},
          bidRequests[0],
          {
            params: {
              placementId: '10433394',
              user: {
                external_uid: '123',
                foobar: 'invalid'
              }
            }
          }
        );
  
        const request = spec.buildRequests([bidRequest]);
        const payload = JSON.parse(request.data);
  
        expect(payload.user).to.exist;
        expect(payload.user).to.deep.equal({
          external_uid: '123',
        });
      });
  
      it('should attach native params to the request', function () {
        let bidRequest = Object.assign({},
          bidRequests[0],
          {
            mediaType: 'native',
            nativeParams: {
              title: {required: true},
              body: {required: true},
              image: {required: true, sizes: [{ width: 100, height: 100 }]},
              cta: {required: false},
              sponsoredBy: {required: true}
            }
          }
        );
  
        const request = spec.buildRequests([bidRequest]);
        const payload = JSON.parse(request.data);
  
        expect(payload.tags[0].native.layouts[0]).to.deep.equal({
          title: {required: true},
          description: {required: true},
          main_image: {required: true, sizes: [{ width: 100, height: 100 }]},
          ctatext: {required: false},
          sponsored_by: {required: true}
        });
      });
  
      it('sets minimum native asset params when not provided on adunit', function () {
        let bidRequest = Object.assign({},
          bidRequests[0],
          {
            mediaType: 'native',
            nativeParams: {
              image: {required: true},
            }
          }
        );
  
        const request = spec.buildRequests([bidRequest]);
        const payload = JSON.parse(request.data);
  
        expect(payload.tags[0].native.layouts[0]).to.deep.equal({
          main_image: {required: true, sizes: [{}]},
        });
      });
  
      it('does not overwrite native ad unit params with mimimum params', function () {
        let bidRequest = Object.assign({},
          bidRequests[0],
          {
            mediaType: 'native',
            nativeParams: {
              image: {
                aspect_ratios: [{
                  min_width: 100,
                  ratio_width: 2,
                  ratio_height: 3,
                }]
              }
            }
          }
        );
  
        const request = spec.buildRequests([bidRequest]);
        const payload = JSON.parse(request.data);
  
        expect(payload.tags[0].native.layouts[0]).to.deep.equal({
          main_image: {
            required: true,
            aspect_ratios: [{
              min_width: 100,
              ratio_width: 2,
              ratio_height: 3,
            }]
          },
        });
      });
  
      it('should convert keyword params to proper form and attaches to request', function () {
        let bidRequest = Object.assign({},
          bidRequests[0],
          {
            params: {
              placementId: '10433394',
              keywords: {
                single: 'val',
                singleArr: ['val'],
                singleArrNum: [5],
                multiValMixed: ['value1', 2, 'value3'],
                singleValNum: 123,
                badValue: {'foo': 'bar'} // should be dropped
              }
            }
          }
        );
  
        const request = spec.buildRequests([bidRequest]);
        const payload = JSON.parse(request.data);
  
        expect(payload.tags[0].keywords).to.deep.equal([{
          'key': 'single',
          'value': ['val']
        }, {
          'key': 'singleArr',
          'value': ['val']
        }, {
          'key': 'singleArrNum',
          'value': ['5']
        }, {
          'key': 'multiValMixed',
          'value': ['value1', '2', 'value3']
        }, {
          'key': 'singleValNum',
          'value': ['123']
        }]);
      });
  
      it('should add payment rules to the request', function () {
        let bidRequest = Object.assign({},
          bidRequests[0],
          {
            params: {
              placementId: '10433394',
              usePaymentRule: true
            }
          }
        );
  
        const request = spec.buildRequests([bidRequest]);
        const payload = JSON.parse(request.data);
  
        expect(payload.tags[0].use_pmt_rule).to.equal(true);
      });
  
      it('should add gdpr consent information to the request', function () {
        let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==';
        let bidderRequest = {
          'bidderCode': 'xhb',
          'auctionId': '1d1a030790a475',
          'bidderRequestId': '22edbae2733bf6',
          'timeout': 3000,
          'gdprConsent': {
            consentString: consentString,
            gdprApplies: true
          }
        };
        bidderRequest.bids = bidRequests;
  
        const request = spec.buildRequests(bidRequests, bidderRequest);
        const payload = JSON.parse(request.data);
  
        expect(payload.gdpr_consent).to.exist;
        expect(payload.gdpr_consent.consent_string).to.exist.and.to.equal(consentString);
        expect(payload.gdpr_consent.consent_required).to.exist.and.to.be.true;
      });
    });
  
    describe('interpretResponse', function () {
      let response = {
        'version': '3.0.0',
        'tags': [
          {
            'uuid': '3db3773286ee59',
            'tag_id': 10433394,
            'auction_id': '4534722592064951574',
            'nobid': false,
            'no_ad_url': 'http://lax1-ib.adnxs.com/no-ad',
            'timeout_ms': 10000,
            'ad_profile_id': 27079,
            'ads': [
              {
                'content_source': 'rtb',
                'ad_type': 'banner',
                'buyer_member_id': 958,
                'creative_id': 29681110,
                'media_type_id': 1,
                'media_subtype_id': 1,
                'cpm': 0.5,
                'cpm_publisher_currency': 0.5,
                'publisher_currency_code': '$',
                'client_initiated_ad_counting': true,
                'rtb': {
                  'banner': {
                    'content': '<!-- Creative -->',
                    'width': 300,
                    'height': 250
                  },
                  'trackers': [
                    {
                      'impression_urls': [
                        'http://lax1-ib.adnxs.com/impression'
                      ],
                      'video_events': {}
                    }
                  ]
                }
              }
            ]
          }
        ]
      };
  
      it('should get correct bid response', function () {
        let expectedResponse = [
          {
            'requestId': '3db3773286ee59',
            'cpm': 0.5,
            'creativeId': 29681110,
            'dealId': undefined,
            'width': 300,
            'height': 250,
            'ad': '<!-- Creative -->',
            'mediaType': 'banner',
            'currency': 'USD',
            'ttl': 300,
            'netRevenue': true,
            'appnexus': {
              'buyerMemberId': 958
            }
          }
        ];
        let bidderRequest;
        let result = spec.interpretResponse({ body: response }, {bidderRequest});
        expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0]));
      });
  
      it('handles nobid responses', function () {
        let response = {
          'version': '0.0.1',
          'tags': [{
            'uuid': '84ab500420319d',
            'tag_id': 5976557,
            'auction_id': '297492697822162468',
            'nobid': true
          }]
        };
        let bidderRequest;
  
        let result = spec.interpretResponse({ body: response }, {bidderRequest});
        expect(result.length).to.equal(0);
      });
  
      it('handles non-banner media responses', function () {
        let response = {
          'tags': [{
            'uuid': '84ab500420319d',
            'ads': [{
              'ad_type': 'video',
              'cpm': 0.500000,
              'notify_url': 'imptracker.com',
              'rtb': {
                'video': {
                  'content': '<!-- Creative -->'
                }
              }
            }]
          }]
        };
        let bidderRequest;
  
        let result = spec.interpretResponse({ body: response }, {bidderRequest});
        expect(result[0]).to.have.property('vastUrl');
        expect(result[0]).to.have.property('vastImpUrl');
        expect(result[0]).to.have.property('mediaType', 'video');
      });
  
      it('handles native responses', function () {
        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('supports configuring outstream renderers', function () {
        const outstreamResponse = deepClone(response);
        outstreamResponse.tags[0].ads[0].rtb.video = {};
        outstreamResponse.tags[0].ads[0].renderer_url = 'renderer.js';
  
        const bidderRequest = {
          bids: [{
            renderer: {
              options: {
                adText: 'configured'
              }
            }
          }]
        };
  
        const result = spec.interpretResponse({ body: outstreamResponse }, {bidderRequest});
        expect(result[0].renderer.config).to.deep.equal(
          bidderRequest.bids[0].renderer.options
        );
      });
    });
  });
  