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