github.com/prebid/prebid-server/v2@v2.18.0/adservertargeting/adservertargeting_test.go (about)

     1  package adservertargeting
     2  
     3  import (
     4  	"encoding/json"
     5  	"net/url"
     6  	"testing"
     7  
     8  	"github.com/prebid/openrtb/v20/openrtb2"
     9  	"github.com/prebid/openrtb/v20/openrtb3"
    10  	"github.com/prebid/prebid-server/v2/openrtb_ext"
    11  	"github.com/prebid/prebid-server/v2/util/jsonutil"
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  func TestExtractAdServerTargeting(t *testing.T) {
    16  
    17  	r := openrtb2.BidRequest{
    18  		ID: "anyID",
    19  		Imp: []openrtb2.Imp{
    20  			{
    21  				ID: "imp1", BidFloor: 10.00,
    22  				Ext: json.RawMessage(`{"prebid": {"is_rewarded_inventory": 1, "test": {"testUser": "user1"}}, "other": "otherImp", "bidder1": {"tagid": 111, "placementId": "test1"}}`),
    23  			},
    24  			{
    25  				ID: "imp2", BidFloor: 20.00,
    26  				Ext: json.RawMessage(`{"prebid": {"is_rewarded_inventory": 1, "test": {"testUser": "user2"}}, "other": "otherImp", "bidder1": {"tagid": 222, "placementId": "test2"}}`),
    27  			},
    28  			{
    29  				ID: "imp3", BidFloor: 30.00,
    30  				Ext: json.RawMessage(`{"prebid": {"is_rewarded_inventory": 1, "test": {"testUser": "user3"}}, "other": "otherImp", "bidder1": {"tagid": 333, "placementId": "test3"}}`),
    31  			},
    32  		},
    33  		User: &openrtb2.User{
    34  			ID:       "testUser",
    35  			Yob:      2000,
    36  			Keywords: "keywords",
    37  		},
    38  		Ext: json.RawMessage(reqExt),
    39  	}
    40  
    41  	rw := &openrtb_ext.RequestWrapper{BidRequest: &r}
    42  
    43  	p := "https://www.test-url.com?ampkey=testAmpKey&data-override-height=400"
    44  	u, _ := url.Parse(p)
    45  	params := u.Query()
    46  	reqBytes, err := jsonutil.Marshal(r)
    47  	assert.NoError(t, err, "unexpected req marshal error")
    48  
    49  	res, warnings := collect(rw, reqBytes, params)
    50  	assert.Len(t, warnings, 2, "incorrect warnings")
    51  	assert.Equal(t, "incorrect value type for path: imp.ext.prebid.test, value can only be string or number", warnings[0].Message, "incorrect warning")
    52  	assert.Equal(t, "incorrect value type for path: ext.prebid.targeting.includebrandcategory, value can only be string or number", warnings[1].Message, "incorrect warning")
    53  
    54  	assert.Len(t, res.RequestTargetingData, 5, "incorrect request targeting data length")
    55  	assert.Len(t, res.ResponseTargetingData, 4, "incorrect response targeting data length")
    56  
    57  	assert.Equal(t, res.RequestTargetingData["hb_amp_param"].SingleVal, json.RawMessage(`testAmpKey`), "incorrect requestTargetingData value for key: hb_amp_param")
    58  
    59  	assert.Len(t, res.RequestTargetingData["hb_req_imp_ext_bidder_param"].TargetingValueByImpId, 3, "incorrect requestTargetingData length for key: hb_req_imp_ext_bidder_param")
    60  	assert.Equal(t, res.RequestTargetingData["hb_req_imp_ext_bidder_param"].TargetingValueByImpId["imp1"], []byte(`111`), "incorrect requestTargetingData value for key: hb_req_imp_ext_bidder_param.imp1")
    61  	assert.Equal(t, res.RequestTargetingData["hb_req_imp_ext_bidder_param"].TargetingValueByImpId["imp2"], []byte(`222`), "incorrect requestTargetingData value for key: hb_req_imp_ext_bidder_param.imp2")
    62  	assert.Equal(t, res.RequestTargetingData["hb_req_imp_ext_bidder_param"].TargetingValueByImpId["imp3"], []byte(`333`), "incorrect requestTargetingData value for key: hb_req_imp_ext_bidder_param.imp3")
    63  
    64  	assert.Len(t, res.RequestTargetingData["hb_req_imp_param"].TargetingValueByImpId, 3, "incorrect requestTargetingData length for key: hb_req_imp_param")
    65  	assert.Equal(t, res.RequestTargetingData["hb_req_imp_param"].TargetingValueByImpId["imp1"], []byte(`10`), "incorrect requestTargetingData value for key: hb_req_imp_param.imp1")
    66  	assert.Equal(t, res.RequestTargetingData["hb_req_imp_param"].TargetingValueByImpId["imp2"], []byte(`20`), "incorrect requestTargetingData value for key: hb_req_imp_param.imp2")
    67  	assert.Equal(t, res.RequestTargetingData["hb_req_imp_param"].TargetingValueByImpId["imp3"], []byte(`30`), "incorrect requestTargetingData value for key: hb_req_imp_param.imp3")
    68  
    69  	assert.Equal(t, res.RequestTargetingData["hb_req_user_param"].SingleVal, json.RawMessage(`2000`), "incorrect requestTargetingData value for key: hb_req_user_param")
    70  	assert.Equal(t, res.RequestTargetingData["hb_static_thing"].SingleVal, json.RawMessage(`test-static-value`), "incorrect requestTargetingData value for key: hb_static_thing")
    71  
    72  	assert.Equal(t, res.ResponseTargetingData[0].Key, "{{BIDDER}}_custom1", "incorrect ResponseTargetingData.Key")
    73  	assert.True(t, res.ResponseTargetingData[0].HasMacro, "incorrect ResponseTargetingData.HasMacro")
    74  	assert.Equal(t, res.ResponseTargetingData[0].Path, "seatbid.bid.ext.custom1", "incorrect ResponseTargetingData.Path")
    75  
    76  	assert.Equal(t, res.ResponseTargetingData[1].Key, "custom2", "incorrect ResponseTargetingData.Key")
    77  	assert.False(t, res.ResponseTargetingData[1].HasMacro, "incorrect ResponseTargetingData.HasMacro")
    78  	assert.Equal(t, res.ResponseTargetingData[1].Path, "seatbid.bid.ext.custom2", "incorrect ResponseTargetingData.Path")
    79  
    80  }
    81  
    82  func TestResolveAdServerTargeting(t *testing.T) {
    83  	nbr := openrtb3.NoBidReason(2)
    84  	resp := &openrtb2.BidResponse{
    85  		ID:         "testResponse",
    86  		Cur:        "USD",
    87  		BidID:      "testBidId",
    88  		CustomData: "testCustomData",
    89  		NBR:        &nbr,
    90  		SeatBid: []openrtb2.SeatBid{
    91  			{
    92  				Seat: "appnexus",
    93  				Bid: []openrtb2.Bid{
    94  					{ID: "bidA1", ImpID: "imp1", Price: 10, Cat: []string{"cat11", "cat12"}, Ext: []byte(`{"prebid": {"foo": "bar1"}}`)},
    95  					{ID: "bidA2", ImpID: "imp2", Price: 20, Cat: []string{"cat21", "cat22"}, Ext: []byte(`{"prebid": {"foo": "bar2"}}`)},
    96  					{ID: "bidA3", ImpID: "imp3", Price: 30, Cat: []string{"cat31", "cat32"}, Ext: []byte(`{"prebid": {"foo": "bar3"}}`)},
    97  				},
    98  				Ext: []byte(`{"testData": {"foo": "barApn"}}`),
    99  			},
   100  			{
   101  				Seat: "rubicon",
   102  				Bid: []openrtb2.Bid{
   103  					{ID: "bidR1", ImpID: "imp1", Price: 11, Cat: []string{"cat111", "cat112"}, Ext: []byte(`{"prebid": {"foo": "bar11", "targeting":{"hb_amp_param":"testInputKey1", "testInput": 111}}}`)},
   104  					{ID: "bidR2", ImpID: "imp2", Price: 22, Cat: []string{"cat221", "cat222"}, Ext: []byte(`{"prebid": {"foo": "bar22", "targeting":{"hb_amp_param":"testInputKey2", "testInput": 222}}}`)},
   105  					{ID: "bidR3", ImpID: "imp3", Price: 33, Cat: []string{"cat331", "cat332"}, Ext: []byte(`{"prebid": {"foo": "bar33", "targeting":{"hb_amp_param":"testInputKey3", "testInput": 333}}}`)},
   106  				},
   107  				Ext: []byte(`{"testData": {"foo": "barRubicon"}}`),
   108  			},
   109  		},
   110  		Ext: []byte(`{"prebid": {"seatExt": "true"}}`),
   111  	}
   112  
   113  	adServerTargeting := &adServerTargetingData{
   114  		RequestTargetingData: map[string]RequestTargetingData{
   115  			"hb_amp_param": {SingleVal: json.RawMessage(`testAmpKey`), TargetingValueByImpId: nil},
   116  			"hb_imp_param": {SingleVal: nil, TargetingValueByImpId: map[string][]byte{
   117  				"imp1": []byte(`111`),
   118  				"imp2": []byte(`222`),
   119  				"imp3": []byte(`333`),
   120  			},
   121  			},
   122  		},
   123  		ResponseTargetingData: []ResponseTargetingData{
   124  			{Key: "{{BIDDER}}_custom1", HasMacro: true, Path: "seatbid.bid.cat"},
   125  			{Key: "custom2", HasMacro: false, Path: "seatbid.bid.ext.prebid.foo"},
   126  			{Key: "custom3", HasMacro: false, Path: "seatbid.bid.price"},
   127  			{Key: "custom4", HasMacro: false, Path: "seatbid.ext.testData.foo"},
   128  			{Key: "custom5", HasMacro: false, Path: "cur"},
   129  			{Key: "custom6", HasMacro: false, Path: "id"},
   130  			{Key: "custom7", HasMacro: false, Path: "bidid"},
   131  			{Key: "custom8", HasMacro: false, Path: "customdata"},
   132  			{Key: "custom9", HasMacro: false, Path: "nbr"},
   133  			{Key: "{{BIDDER}}_custom6", HasMacro: true, Path: "ext.prebid.seatExt"},
   134  		},
   135  	}
   136  	bidResponse, warnings := resolve(adServerTargeting, resp, nil, nil)
   137  
   138  	assert.Len(t, warnings, 6, "incorrect warnings number")
   139  	assert.NotNil(t, bidResponse, "incorrect resolved targeting data")
   140  	assert.Len(t, bidResponse.SeatBid, 2, "incorrect seat bids number")
   141  
   142  	assert.Len(t, bidResponse.SeatBid[0].Bid, 3, "incorrect bids number for bidder : %", "appnexus")
   143  	assert.Len(t, bidResponse.SeatBid[1].Bid, 3, "incorrect bids number for bidder : %", "rubicon")
   144  
   145  	assert.JSONEq(t, seatBid0Bid0Ext, string(bidResponse.SeatBid[0].Bid[0].Ext), "incorrect ext for SeatBid[0].Bid[0]")
   146  	assert.JSONEq(t, seatBid0Bid1Ext, string(bidResponse.SeatBid[0].Bid[1].Ext), "incorrect ext for SeatBid[0].Bid[1]")
   147  	assert.JSONEq(t, seatBid0Bid2Ext, string(bidResponse.SeatBid[0].Bid[2].Ext), "incorrect ext for SeatBid[0].Bid[2]")
   148  	assert.JSONEq(t, seatBid1Bid0Ext, string(bidResponse.SeatBid[1].Bid[0].Ext), "incorrect ext for SeatBid[1].Bid[0]")
   149  	assert.JSONEq(t, seatBid1Bid1Ext, string(bidResponse.SeatBid[1].Bid[1].Ext), "incorrect ext for SeatBid[1].Bid[1]")
   150  	assert.JSONEq(t, seatBid1Bid2Ext, string(bidResponse.SeatBid[1].Bid[2].Ext), "incorrect ext for SeatBid[1].Bid[2]")
   151  
   152  }
   153  
   154  func TestResolveAdServerTargetingForMultiBidAndOneImp(t *testing.T) {
   155  	resp := &openrtb2.BidResponse{
   156  		ID:  "testResponse",
   157  		Cur: "USD",
   158  		SeatBid: []openrtb2.SeatBid{
   159  			{
   160  				Seat: "appnexus",
   161  				Bid: []openrtb2.Bid{
   162  					{ID: "bidA1", ImpID: "imp1", Price: 10, Cat: []string{"cat11", "cat12"}, Ext: []byte(`{"prebid": {"foo": "bar1"}}`)},
   163  					{ID: "bidA2", ImpID: "imp1", Price: 20, Cat: []string{"cat21", "cat22"}, Ext: []byte(`{"prebid": {"foo": "bar2"}}`)},
   164  					{ID: "bidA3", ImpID: "imp1", Price: 30, Cat: []string{"cat31", "cat32"}, Ext: []byte(`{"prebid": {"foo": "bar3"}}`)},
   165  				},
   166  				Ext: []byte(`{"testData": {"foo": "barApn"}}`),
   167  			},
   168  		},
   169  		Ext: []byte(`{"prebid": {"seatExt": "true"}}`),
   170  	}
   171  
   172  	adServerTargeting := &adServerTargetingData{
   173  		RequestTargetingData: nil,
   174  		ResponseTargetingData: []ResponseTargetingData{
   175  			{Key: "custom_attribute", HasMacro: false, Path: "seatbid.bid.ext.prebid.foo"},
   176  		},
   177  	}
   178  	truncateTargetingAttr := 11
   179  	bidResponse, warnings := resolve(adServerTargeting, resp, nil, &truncateTargetingAttr)
   180  
   181  	assert.Empty(t, warnings, "unexpected error")
   182  	assert.Equal(t, bidResponse.ID, "testResponse", "incorrect")
   183  	assert.Len(t, bidResponse.SeatBid, 1, "incorrect seat bids number")
   184  	assert.Len(t, bidResponse.SeatBid[0].Bid, 3, "incorrect bids number")
   185  
   186  	assert.JSONEq(t, bid0Ext, string(bidResponse.SeatBid[0].Bid[0].Ext), "incorrect ext for SeatBid[0].Bid[0]")
   187  	assert.JSONEq(t, bid1Ext, string(bidResponse.SeatBid[0].Bid[1].Ext), "incorrect ext for SeatBid[0].Bid[1]")
   188  	assert.JSONEq(t, bid2Ext, string(bidResponse.SeatBid[0].Bid[2].Ext), "incorrect ext for SeatBid[0].Bid[2]")
   189  
   190  }
   191  
   192  func TestProcessAdServerTargetingFull(t *testing.T) {
   193  
   194  	r := openrtb2.BidRequest{
   195  		ID: "anyID",
   196  		Imp: []openrtb2.Imp{
   197  			{
   198  				ID: "imp1", BidFloor: 10.00,
   199  				Ext: json.RawMessage(`{"prebid": {"is_rewarded_inventory": 1, "test": {"testUser": "user1"}}, "other": "otherImp", "bidder1": {"tagid": 111, "placementId": "test1"}}`),
   200  			},
   201  			{
   202  				ID: "imp2", BidFloor: 20.00,
   203  				Ext: json.RawMessage(`{"prebid": {"is_rewarded_inventory": 1, "test": {"testUser": "user2"}}, "other": "otherImp", "bidder1": {"tagid": 222, "placementId": "test2"}}`),
   204  			},
   205  			{
   206  				ID: "imp3", BidFloor: 30.00,
   207  				Ext: json.RawMessage(`{"prebid": {"is_rewarded_inventory": 1, "test": {"testUser": "user3"}}, "other": "otherImp", "bidder1": {"tagid": 333, "placementId": "test3"}}`),
   208  			},
   209  		},
   210  		User: &openrtb2.User{
   211  			ID:       "testUser",
   212  			Yob:      2000,
   213  			Keywords: "keywords",
   214  		},
   215  		Ext: json.RawMessage(reqExt),
   216  	}
   217  
   218  	rw := &openrtb_ext.RequestWrapper{BidRequest: &r}
   219  
   220  	p := "https://www.test-url.com?ampkey=testAmpKey&data-override-height=400"
   221  	u, _ := url.Parse(p)
   222  	params := u.Query()
   223  
   224  	resp := &openrtb2.BidResponse{
   225  		ID:  "testResponse",
   226  		Cur: "USD",
   227  		SeatBid: []openrtb2.SeatBid{
   228  			{
   229  				Seat: "appnexus",
   230  				Bid: []openrtb2.Bid{
   231  					{ID: "bidA1", ImpID: "imp1", Price: 10, Cat: []string{"cat11", "cat12"}, Ext: []byte(`{"prebid": {"foo": "bar1"}, "custom1": 1111, "custom2": "a1111"}`)},
   232  					{ID: "bidA2", ImpID: "imp2", Price: 20, Cat: []string{"cat21", "cat22"}, Ext: []byte(`{"prebid": {"foo": "bar2"}, "custom1": 2222, "custom2": "a2222"}`)},
   233  					{ID: "bidA3", ImpID: "imp3", Price: 30, Cat: []string{"cat31", "cat32"}, Ext: []byte(`{"prebid": {"foo": "bar3"}, "custom1": 3333, "custom2": "a3333"}`)},
   234  				},
   235  				Ext: []byte(`{"testData": {"foo": "barApn"}}`),
   236  			},
   237  			{
   238  				Seat: "rubicon",
   239  				Bid: []openrtb2.Bid{
   240  					{ID: "bidR1", ImpID: "imp1", Price: 11, Cat: []string{"cat111", "cat112"}, Ext: []byte(`{"custom1": 4444, "custom2": "r4444", "prebid": {"foo": "bar11", "targeting":{"hb_amp_param":"testInputKey1", "testInput": 111}}}`)},
   241  					{ID: "bidR2", ImpID: "imp2", Price: 22, Cat: []string{"cat221", "cat222"}, Ext: []byte(`{"custom1": 5555, "custom2": "r5555", "prebid": {"foo": "bar22", "targeting":{"hb_amp_param":"testInputKey2", "testInput": 222}}}`)},
   242  					{ID: "bidR3", ImpID: "imp3", Price: 33, Cat: []string{"cat331", "cat332"}, Ext: []byte(`{"custom1": 6666, "custom2": "r6666", "prebid": {"foo": "bar33", "targeting":{"hb_amp_param":"testInputKey3", "testInput": 333}}}`)},
   243  				},
   244  				Ext: []byte(`{"testData": {"foo": "barRubicon"}}`),
   245  			},
   246  		},
   247  		Ext: []byte(`{"prebid": {"seatExt": "true"}}`),
   248  	}
   249  
   250  	bidResponseExt := &openrtb_ext.ExtBidResponse{Warnings: make(map[openrtb_ext.BidderName][]openrtb_ext.ExtBidderMessage)}
   251  
   252  	reqBytes, err := jsonutil.Marshal(r)
   253  	assert.NoError(t, err, "unexpected req marshal error")
   254  	targetingKeyLen := 0
   255  	resResp := Apply(rw, reqBytes, resp, params, bidResponseExt, &targetingKeyLen)
   256  	assert.Len(t, resResp.SeatBid, 2, "incorrect response: seat bid number")
   257  	assert.Len(t, bidResponseExt.Warnings[openrtb_ext.BidderReservedGeneral], 2, "incorrect warnings number")
   258  	assert.Equal(t, "incorrect value type for path: imp.ext.prebid.test, value can only be string or number", bidResponseExt.Warnings[openrtb_ext.BidderReservedGeneral][0].Message, "incorrect warning")
   259  	assert.Equal(t, "incorrect value type for path: ext.prebid.targeting.includebrandcategory, value can only be string or number", bidResponseExt.Warnings[openrtb_ext.BidderReservedGeneral][1].Message, "incorrect warning")
   260  
   261  	apnBids := resResp.SeatBid[0].Bid
   262  	rbcBids := resResp.SeatBid[1].Bid
   263  
   264  	assert.Len(t, apnBids, 3, "Incorrect response: appnexus bids number")
   265  	assert.Len(t, rbcBids, 3, "Incorrect response: rubicon bid number")
   266  
   267  	assert.JSONEq(t, apnBid0Ext, string(apnBids[0].Ext), "incorrect ext for appnexus bid[0]")
   268  	assert.JSONEq(t, apnBid1Ext, string(apnBids[1].Ext), "incorrect ext for appnexus bid[1]")
   269  	assert.JSONEq(t, apnBid2Ext, string(apnBids[2].Ext), "incorrect ext for appnexus bid[2]")
   270  
   271  	assert.JSONEq(t, rbcBid0Ext, string(rbcBids[0].Ext), "incorrect ext for rubicon bid[0]")
   272  	assert.JSONEq(t, rbcBid1Ext, string(rbcBids[1].Ext), "incorrect ext for rubicon bid[1]")
   273  	assert.JSONEq(t, rbcBid2Ext, string(rbcBids[2].Ext), "incorrect ext for rubicon bid[2]")
   274  
   275  }
   276  
   277  func TestProcessAdServerTargetingWarnings(t *testing.T) {
   278  
   279  	r := openrtb2.BidRequest{
   280  		ID: "anyID",
   281  		Imp: []openrtb2.Imp{
   282  			{
   283  				ID:  "imp1",
   284  				Ext: json.RawMessage(`{"prebid": {"is_rewarded_inventory": 1 }, "other": "otherImp", "bidder1": {"placementId": "test1"}}`),
   285  			},
   286  			{
   287  				ID:  "imp2",
   288  				Ext: json.RawMessage(`{"prebid": {"is_rewarded_inventory": 1}, "other": "otherImp", "bidder1": {"placementId": "test2"}}`),
   289  			},
   290  			{
   291  				ID:  "imp3",
   292  				Ext: json.RawMessage(`{"prebid": {"is_rewarded_inventory": 1}, "other": "otherImp", "bidder1": {"placementId": "test3"}}`),
   293  			},
   294  		},
   295  		User: &openrtb2.User{
   296  			ID:       "testUser",
   297  			Keywords: "keywords",
   298  		},
   299  		Ext: json.RawMessage(reqExt),
   300  	}
   301  
   302  	rw := &openrtb_ext.RequestWrapper{BidRequest: &r}
   303  
   304  	p := "https://www.test-url.com?data-override-height=400"
   305  	u, _ := url.Parse(p)
   306  	params := u.Query()
   307  
   308  	resp := &openrtb2.BidResponse{
   309  		ID: "testResponse",
   310  		SeatBid: []openrtb2.SeatBid{
   311  			{
   312  				Seat: "appnexus",
   313  				Bid: []openrtb2.Bid{
   314  					{ID: "bidA1", ImpID: "imp1", Price: 10, Cat: []string{"cat11", "cat12"}, Ext: []byte(`{"prebid": {"foo": "bar1"}}`)},
   315  					{ID: "bidA2", ImpID: "imp2", Price: 20, Cat: []string{"cat21", "cat22"}, Ext: []byte(`{"prebid": {"foo": "bar2"}}`)},
   316  					{ID: "bidA3", ImpID: "imp3", Price: 30, Cat: []string{"cat31", "cat32"}, Ext: []byte(`{"prebid": {"foo": "bar3"}}`)},
   317  				},
   318  				Ext: []byte(`{"testData": {"foo": "barApn"}}`),
   319  			},
   320  			{
   321  				Seat: "rubicon",
   322  				Bid: []openrtb2.Bid{
   323  					{ID: "bidR1", ImpID: "imp1", Price: 11, Cat: []string{"cat111", "cat112"}, Ext: []byte(`{"prebid": {"foo": "bar11", "targeting":{"hb_amp_param":"testInputKey1", "testInput": 111}}}`)},
   324  					{ID: "bidR2", ImpID: "imp2", Price: 22, Cat: []string{"cat221", "cat222"}, Ext: []byte(`{"prebid": {"foo": "bar22", "targeting":{"hb_amp_param":"testInputKey2", "testInput": 222}}}`)},
   325  					{ID: "bidR3", ImpID: "imp3", Price: 33, Cat: []string{"cat331", "cat332"}, Ext: []byte(`{"prebid": {"foo": "bar33", "targeting":{"hb_amp_param":"testInputKey3", "testInput": 333}}}`)},
   326  				},
   327  				Ext: []byte(`{"testData": {"foo": "barRubicon"}}`),
   328  			},
   329  		},
   330  		Ext: []byte(`{"prebid": {"seatExt": "true"}}`),
   331  	}
   332  
   333  	bidResponseExt := &openrtb_ext.ExtBidResponse{Warnings: make(map[openrtb_ext.BidderName][]openrtb_ext.ExtBidderMessage)}
   334  
   335  	reqBytes, err := jsonutil.Marshal(r)
   336  	assert.NoError(t, err, "unexpected req marshal error")
   337  	resResp := Apply(rw, reqBytes, resp, params, bidResponseExt, nil)
   338  	assert.Len(t, resResp.SeatBid, 2, "Incorrect response: seat bid number")
   339  
   340  	apnBids := resResp.SeatBid[0].Bid
   341  	rbcBids := resResp.SeatBid[1].Bid
   342  
   343  	assert.Len(t, apnBids, 3, "Incorrect response: appnexus bids number")
   344  	assert.Len(t, rbcBids, 3, "Incorrect response: rubicon bid number")
   345  
   346  	warnings := bidResponseExt.Warnings[openrtb_ext.BidderReservedGeneral]
   347  	assert.Len(t, warnings, 18, "Incorrect response: seat bid number")
   348  	assert.Equal(t, "value not found for path: ext.prebid.amp.data.ampkey", warnings[0].Message, "Incorrect warning")
   349  	assert.Equal(t, "value not found for path: imp.ext.prebid.test", warnings[1].Message, "Incorrect warning")
   350  	assert.Equal(t, "value not found for path: imp.ext.bidder1.tagid", warnings[2].Message, "Incorrect warning")
   351  	assert.Equal(t, "value not found for path: imp.bidfloor", warnings[3].Message, "Incorrect warning")
   352  	assert.Equal(t, "incorrect value type for path: ext.prebid.targeting.includebrandcategory, value can only be string or number", warnings[4].Message, "Incorrect warning")
   353  	assert.Equal(t, "value not found for path: user.yob", warnings[5].Message, "Incorrect warning")
   354  
   355  	assert.Equal(t, "value not found for path: ext.custom1 for bidder: appnexus, bid id: bidA1", warnings[6].Message, "Incorrect warning")
   356  	assert.Equal(t, "value not found for path: ext.custom2 for bidder: appnexus, bid id: bidA1", warnings[7].Message, "Incorrect warning")
   357  	assert.Equal(t, "value not found for path: ext.custom1 for bidder: appnexus, bid id: bidA2", warnings[8].Message, "Incorrect warning")
   358  	assert.Equal(t, "value not found for path: ext.custom2 for bidder: appnexus, bid id: bidA2", warnings[9].Message, "Incorrect warning")
   359  	assert.Equal(t, "value not found for path: ext.custom1 for bidder: appnexus, bid id: bidA3", warnings[10].Message, "Incorrect warning")
   360  	assert.Equal(t, "value not found for path: ext.custom2 for bidder: appnexus, bid id: bidA3", warnings[11].Message, "Incorrect warning")
   361  	assert.Equal(t, "value not found for path: ext.custom1 for bidder: rubicon, bid id: bidR1", warnings[12].Message, "Incorrect warning")
   362  	assert.Equal(t, "value not found for path: ext.custom2 for bidder: rubicon, bid id: bidR1", warnings[13].Message, "Incorrect warning")
   363  	assert.Equal(t, "value not found for path: ext.custom1 for bidder: rubicon, bid id: bidR2", warnings[14].Message, "Incorrect warning")
   364  	assert.Equal(t, "value not found for path: ext.custom2 for bidder: rubicon, bid id: bidR2", warnings[15].Message, "Incorrect warning")
   365  	assert.Equal(t, "value not found for path: ext.custom1 for bidder: rubicon, bid id: bidR3", warnings[16].Message, "Incorrect warning")
   366  	assert.Equal(t, "value not found for path: ext.custom2 for bidder: rubicon, bid id: bidR3", warnings[17].Message, "Incorrect warning")
   367  }