github.com/prebid/prebid-server/v2@v2.18.0/adapters/ix/ix_test.go (about) 1 package ix 2 3 import ( 4 "encoding/json" 5 "testing" 6 7 "github.com/prebid/prebid-server/v2/adapters" 8 "github.com/prebid/prebid-server/v2/adapters/adapterstest" 9 "github.com/prebid/prebid-server/v2/config" 10 "github.com/prebid/prebid-server/v2/openrtb_ext" 11 "github.com/prebid/prebid-server/v2/util/ptrutil" 12 "github.com/prebid/prebid-server/v2/version" 13 "github.com/stretchr/testify/assert" 14 15 "github.com/prebid/openrtb/v20/adcom1" 16 "github.com/prebid/openrtb/v20/openrtb2" 17 ) 18 19 const endpoint string = "http://host/endpoint" 20 21 func TestJsonSamples(t *testing.T) { 22 if bidder, err := Builder(openrtb_ext.BidderIx, config.Adapter{Endpoint: endpoint}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}); err == nil { 23 adapterstest.RunJSONBidderTest(t, "ixtest", bidder) 24 } else { 25 t.Fatalf("Builder returned unexpected error %v", err) 26 } 27 } 28 29 func TestIxMakeBidsWithCategoryDuration(t *testing.T) { 30 bidder := &IxAdapter{} 31 32 mockedReq := &openrtb2.BidRequest{ 33 Imp: []openrtb2.Imp{{ 34 ID: "1_1", 35 Video: &openrtb2.Video{ 36 W: ptrutil.ToPtr[int64](640), 37 H: ptrutil.ToPtr[int64](360), 38 MIMEs: []string{"video/mp4"}, 39 MaxDuration: 60, 40 Protocols: []adcom1.MediaCreativeSubtype{2, 3, 5, 6}, 41 }, 42 Ext: json.RawMessage( 43 `{ 44 "prebid": {}, 45 "bidder": { 46 "siteID": "123456" 47 } 48 }`, 49 )}, 50 }, 51 } 52 mockedExtReq := &adapters.RequestData{} 53 mockedBidResponse := &openrtb2.BidResponse{ 54 ID: "test-1", 55 SeatBid: []openrtb2.SeatBid{{ 56 Seat: "Buyer", 57 Bid: []openrtb2.Bid{{ 58 ID: "1", 59 ImpID: "1_1", 60 Price: 1.23, 61 AdID: "123", 62 Ext: json.RawMessage( 63 `{ 64 "prebid": { 65 "video": { 66 "duration": 60, 67 "primary_category": "IAB18-1" 68 } 69 } 70 }`, 71 ), 72 }}, 73 }}, 74 } 75 body, _ := json.Marshal(mockedBidResponse) 76 mockedRes := &adapters.ResponseData{ 77 StatusCode: 200, 78 Body: body, 79 } 80 81 expectedBidCount := 1 82 expectedBidType := openrtb_ext.BidTypeVideo 83 expectedBidDuration := 60 84 expectedBidCategory := "IAB18-1" 85 expectedErrorCount := 0 86 87 bidResponse, errors := bidder.MakeBids(mockedReq, mockedExtReq, mockedRes) 88 89 if len(bidResponse.Bids) != expectedBidCount { 90 t.Errorf("should have 1 bid, bids=%v", bidResponse.Bids) 91 } 92 if bidResponse.Bids[0].BidType != expectedBidType { 93 t.Errorf("bid type should be video, bidType=%s", bidResponse.Bids[0].BidType) 94 } 95 if bidResponse.Bids[0].BidVideo.Duration != expectedBidDuration { 96 t.Errorf("video duration should be set") 97 } 98 if bidResponse.Bids[0].Bid.Cat[0] != expectedBidCategory { 99 t.Errorf("bid category should be set") 100 } 101 if len(errors) != expectedErrorCount { 102 t.Errorf("should not have any errors, errors=%v", errors) 103 } 104 } 105 106 func TestIxMakeRequestWithGppString(t *testing.T) { 107 bidder := &IxAdapter{} 108 109 testGppString := "DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN" 110 111 mockedReq := &openrtb2.BidRequest{ 112 Imp: []openrtb2.Imp{{ 113 ID: "1_1", 114 Video: &openrtb2.Video{ 115 W: ptrutil.ToPtr[int64](640), 116 H: ptrutil.ToPtr[int64](360), 117 MIMEs: []string{"video/mp4"}, 118 MaxDuration: 60, 119 Protocols: []adcom1.MediaCreativeSubtype{2, 3, 5, 6}, 120 }, 121 Ext: json.RawMessage( 122 `{ 123 "prebid": {}, 124 "bidder": { 125 "siteId": "123456" 126 } 127 }`, 128 )}, 129 }, 130 Regs: &openrtb2.Regs{ 131 GPP: testGppString, 132 }, 133 } 134 135 expectedRequestCount := 1 136 expectedErrorCount := 0 137 var reqInfo *adapters.ExtraRequestInfo 138 139 requests, errors := bidder.MakeRequests(mockedReq, reqInfo) 140 141 if len(requests) != expectedRequestCount { 142 t.Errorf("should have 1 request, requests=%v", requests) 143 } 144 145 if len(errors) != expectedErrorCount { 146 t.Errorf("should not have any errors, errors=%v", errors) 147 } 148 149 req := &openrtb2.BidRequest{} 150 json.Unmarshal(requests[0].Body, req) 151 152 assert.Equal(t, req.Regs.GPP, testGppString) 153 } 154 155 func TestBuildIxDiag(t *testing.T) { 156 testCases := []struct { 157 description string 158 request *openrtb2.BidRequest 159 expectedRequest *openrtb2.BidRequest 160 expectError bool 161 pbsVersion string 162 }{ 163 { 164 description: "Base Test", 165 request: &openrtb2.BidRequest{ 166 ID: "1", 167 Ext: json.RawMessage(`{"prebid":{"channel":{"name":"web","version":"7.20"}}}`), 168 }, 169 expectedRequest: &openrtb2.BidRequest{ 170 ID: "1", 171 Ext: json.RawMessage(`{"prebid":{"channel":{"name":"web","version":"7.20"}},"ixdiag":{"pbsv":"1.880","pbjsv":"7.20"}}`), 172 }, 173 expectError: false, 174 pbsVersion: "1.880-abcdef", 175 }, 176 { 177 description: "Base test for nil channel but non-empty ext prebid payload", 178 request: &openrtb2.BidRequest{ 179 ID: "1", 180 Ext: json.RawMessage(`{"prebid":{"server":{"externalurl":"http://localhost:8000"}}}`), 181 }, 182 expectedRequest: &openrtb2.BidRequest{ 183 ID: "1", 184 Ext: json.RawMessage(`{"prebid":{"server":{"externalurl":"http://localhost:8000","gvlid":0,"datacenter":""}},"ixdiag":{"pbsv":"1.880"}}`), 185 }, 186 expectError: false, 187 pbsVersion: "1.880-abcdef", 188 }, 189 { 190 description: "No Ext", 191 request: &openrtb2.BidRequest{ 192 ID: "1", 193 }, 194 expectedRequest: &openrtb2.BidRequest{ 195 ID: "1", 196 Ext: json.RawMessage(`{"prebid":null,"ixdiag":{"pbsv":"1.880"}}`), 197 }, 198 expectError: false, 199 pbsVersion: "1.880-abcdef", 200 }, 201 { 202 description: "PBS Version Two Hypens", 203 request: &openrtb2.BidRequest{ 204 ID: "1", 205 }, 206 expectedRequest: &openrtb2.BidRequest{ 207 ID: "1", 208 Ext: json.RawMessage(`{"prebid":null,"ixdiag":{"pbsv":"0.23.1"}}`), 209 }, 210 expectError: false, 211 pbsVersion: "0.23.1-3-g4ee257d8", 212 }, 213 { 214 description: "PBS Version no Hyphen", 215 request: &openrtb2.BidRequest{ 216 ID: "1", 217 Ext: json.RawMessage(`{"prebid":{"channel":{"name":"web","version":"7.20"}}}`), 218 }, 219 expectedRequest: &openrtb2.BidRequest{ 220 ID: "1", 221 Ext: json.RawMessage(`{"prebid":{"channel":{"name":"web","version":"7.20"}},"ixdiag":{"pbsv":"1.880","pbjsv":"7.20"}}`), 222 }, 223 expectError: false, 224 pbsVersion: "1.880", 225 }, 226 { 227 description: "PBS Version empty string", 228 request: &openrtb2.BidRequest{ 229 ID: "1", 230 Ext: json.RawMessage(`{"prebid":{"channel":{"name":"web","version":"7.20"}}}`), 231 }, 232 expectedRequest: &openrtb2.BidRequest{ 233 ID: "1", 234 Ext: json.RawMessage(`{"prebid":{"channel":{"name":"web","version":"7.20"}},"ixdiag":{"pbjsv":"7.20"}}`), 235 }, 236 expectError: false, 237 pbsVersion: "", 238 }, 239 { 240 description: "Error Test", 241 request: &openrtb2.BidRequest{ 242 ID: "1", 243 Ext: json.RawMessage(`{"prebid":"channel":{"name":"web","version":"7.20"}}}`), 244 }, 245 expectedRequest: &openrtb2.BidRequest{ 246 ID: "1", 247 Ext: nil, 248 }, 249 expectError: true, 250 pbsVersion: "1.880-abcdef", 251 }, 252 } 253 254 for _, test := range testCases { 255 t.Run(test.description, func(t *testing.T) { 256 version.Ver = test.pbsVersion 257 ixDiag := &IxDiag{} 258 err := setIxDiagIntoExtRequest(test.request, ixDiag) 259 if test.expectError { 260 assert.NotNil(t, err) 261 } else { 262 assert.Equal(t, test.expectedRequest, test.request) 263 assert.Nil(t, err) 264 } 265 }) 266 } 267 } 268 269 func TestMakeRequestsErrIxDiag(t *testing.T) { 270 bidder := &IxAdapter{} 271 req := &openrtb2.BidRequest{ 272 ID: "1", 273 Ext: json.RawMessage(`{"prebid":"channel":{"name":"web","version":"7.20"}}}`), 274 } 275 _, errs := bidder.MakeRequests(req, nil) 276 assert.Len(t, errs, 1) 277 } 278 279 func TestPABidResponse(t *testing.T) { 280 bidder := &IxAdapter{} 281 282 mockedReq := &openrtb2.BidRequest{ 283 Imp: []openrtb2.Imp{{ 284 ID: "1_1", 285 Banner: &openrtb2.Banner{ 286 Format: []openrtb2.Format{{W: 300, H: 250}}, 287 }, 288 Ext: json.RawMessage( 289 `{ 290 "ae": 1, 291 "bidder": { 292 "siteID": "123456" 293 } 294 }`, 295 )}, 296 }, 297 } 298 mockedExtReq := &adapters.RequestData{} 299 mockedBidResponse := &openrtb2.BidResponse{ 300 ID: "test-1", 301 SeatBid: []openrtb2.SeatBid{{ 302 Seat: "Buyer", 303 Bid: []openrtb2.Bid{{ 304 ID: "1", 305 ImpID: "1_1", 306 Price: 1.23, 307 AdID: "123", 308 Ext: json.RawMessage( 309 `{ 310 "prebid": { 311 "video": { 312 "duration": 60, 313 "primary_category": "IAB18-1" 314 } 315 } 316 }`, 317 ), 318 }}, 319 }}, 320 } 321 322 testCases := []struct { 323 name string 324 ext json.RawMessage 325 expectedLen int 326 }{ 327 { 328 name: "properly formatted", 329 ext: json.RawMessage( 330 `{ 331 "protectedAudienceAuctionConfigs": [{ 332 "bidId": "test-imp-id", 333 "config": { 334 "seller": "https://seller.com", 335 "decisionLogicUrl": "https://ssp.com/decision-logic.js", 336 "interestGroupBuyers": [ 337 "https://buyer.com" 338 ], 339 "sellerSignals": { 340 "callbackUrl": "https://callbackurl.com" 341 }, 342 "perBuyerSignals": { 343 "https://buyer.com": [] 344 } 345 } 346 }] 347 }`, 348 ), 349 expectedLen: 1, 350 }, 351 { 352 name: "no protected audience auction configs returned", 353 ext: json.RawMessage(`{}`), 354 expectedLen: 0, 355 }, 356 { 357 name: "no config", 358 ext: json.RawMessage( 359 `{ 360 "protectedAudienceAuctionConfigs": [{ 361 "bidId": "test-imp-id" 362 }] 363 }`, 364 ), 365 expectedLen: 0, 366 }, 367 } 368 369 for _, tc := range testCases { 370 t.Run(tc.name, func(t *testing.T) { 371 mockedBidResponse.Ext = tc.ext 372 body, _ := json.Marshal(mockedBidResponse) 373 mockedRes := &adapters.ResponseData{ 374 StatusCode: 200, 375 Body: body, 376 } 377 bidResponse, errors := bidder.MakeBids(mockedReq, mockedExtReq, mockedRes) 378 379 assert.Nil(t, errors) 380 assert.Len(t, bidResponse.FledgeAuctionConfigs, tc.expectedLen) 381 }) 382 } 383 }