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 }