github.com/prebid/prebid-server/v2@v2.18.0/adapters/pubmatic/pubmatic_test.go (about) 1 package pubmatic 2 3 import ( 4 "encoding/json" 5 "net/http" 6 "sort" 7 "strings" 8 "testing" 9 10 "github.com/prebid/openrtb/v20/openrtb2" 11 "github.com/prebid/prebid-server/v2/adapters" 12 "github.com/prebid/prebid-server/v2/adapters/adapterstest" 13 "github.com/prebid/prebid-server/v2/config" 14 "github.com/prebid/prebid-server/v2/openrtb_ext" 15 "github.com/stretchr/testify/assert" 16 ) 17 18 func TestJsonSamples(t *testing.T) { 19 bidder, buildErr := Builder(openrtb_ext.BidderPubmatic, config.Adapter{ 20 Endpoint: "https://hbopenbid.pubmatic.com/translator?source=prebid-server"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) 21 22 if buildErr != nil { 23 t.Fatalf("Builder returned unexpected error %v", buildErr) 24 } 25 26 adapterstest.RunJSONBidderTest(t, "pubmatictest", bidder) 27 } 28 29 func TestGetBidTypeVideo(t *testing.T) { 30 pubmaticExt := &pubmaticBidExt{} 31 pubmaticExt.BidType = new(int) 32 *pubmaticExt.BidType = 1 33 actualBidTypeValue := getBidType(pubmaticExt) 34 if actualBidTypeValue != openrtb_ext.BidTypeVideo { 35 t.Errorf("Expected Bid Type value was: %v, actual value is: %v", openrtb_ext.BidTypeVideo, actualBidTypeValue) 36 } 37 } 38 39 func TestGetBidTypeForMissingBidTypeExt(t *testing.T) { 40 pubmaticExt := &pubmaticBidExt{} 41 actualBidTypeValue := getBidType(pubmaticExt) 42 // banner is the default bid type when no bidType key is present in the bid.ext 43 if actualBidTypeValue != "banner" { 44 t.Errorf("Expected Bid Type value was: banner, actual value is: %v", actualBidTypeValue) 45 } 46 } 47 48 func TestGetBidTypeBanner(t *testing.T) { 49 pubmaticExt := &pubmaticBidExt{} 50 pubmaticExt.BidType = new(int) 51 *pubmaticExt.BidType = 0 52 actualBidTypeValue := getBidType(pubmaticExt) 53 if actualBidTypeValue != openrtb_ext.BidTypeBanner { 54 t.Errorf("Expected Bid Type value was: %v, actual value is: %v", openrtb_ext.BidTypeBanner, actualBidTypeValue) 55 } 56 } 57 58 func TestGetBidTypeNative(t *testing.T) { 59 pubmaticExt := &pubmaticBidExt{} 60 pubmaticExt.BidType = new(int) 61 *pubmaticExt.BidType = 2 62 actualBidTypeValue := getBidType(pubmaticExt) 63 if actualBidTypeValue != openrtb_ext.BidTypeNative { 64 t.Errorf("Expected Bid Type value was: %v, actual value is: %v", openrtb_ext.BidTypeNative, actualBidTypeValue) 65 } 66 } 67 68 func TestGetBidTypeForUnsupportedCode(t *testing.T) { 69 pubmaticExt := &pubmaticBidExt{} 70 pubmaticExt.BidType = new(int) 71 *pubmaticExt.BidType = 99 72 actualBidTypeValue := getBidType(pubmaticExt) 73 if actualBidTypeValue != openrtb_ext.BidTypeBanner { 74 t.Errorf("Expected Bid Type value was: %v, actual value is: %v", openrtb_ext.BidTypeBanner, actualBidTypeValue) 75 } 76 } 77 78 func TestParseImpressionObject(t *testing.T) { 79 type args struct { 80 imp *openrtb2.Imp 81 extractWrapperExtFromImp bool 82 extractPubIDFromImp bool 83 } 84 tests := []struct { 85 name string 86 args args 87 expectedWrapperExt *pubmaticWrapperExt 88 expectedPublisherId string 89 wantErr bool 90 expectedBidfloor float64 91 }{ 92 { 93 name: "imp.bidfloor empty and kadfloor set", 94 args: args{ 95 imp: &openrtb2.Imp{ 96 Video: &openrtb2.Video{}, 97 Ext: json.RawMessage(`{"bidder":{"kadfloor":"0.12"}}`), 98 }, 99 }, 100 expectedBidfloor: 0.12, 101 }, 102 { 103 name: "imp.bidfloor set and kadfloor empty", 104 args: args{ 105 imp: &openrtb2.Imp{ 106 BidFloor: 0.12, 107 Video: &openrtb2.Video{}, 108 Ext: json.RawMessage(`{"bidder":{}}`), 109 }, 110 }, 111 expectedBidfloor: 0.12, 112 }, 113 { 114 name: "imp.bidfloor set and kadfloor invalid", 115 args: args{ 116 imp: &openrtb2.Imp{ 117 BidFloor: 0.12, 118 Video: &openrtb2.Video{}, 119 Ext: json.RawMessage(`{"bidder":{"kadfloor":"aaa"}}`), 120 }, 121 }, 122 expectedBidfloor: 0.12, 123 }, 124 { 125 name: "imp.bidfloor set and kadfloor set, higher imp.bidfloor", 126 args: args{ 127 imp: &openrtb2.Imp{ 128 BidFloor: 0.12, 129 Video: &openrtb2.Video{}, 130 Ext: json.RawMessage(`{"bidder":{"kadfloor":"0.11"}}`), 131 }, 132 }, 133 expectedBidfloor: 0.12, 134 }, 135 { 136 name: "imp.bidfloor set and kadfloor set, higher kadfloor", 137 args: args{ 138 imp: &openrtb2.Imp{ 139 BidFloor: 0.12, 140 Video: &openrtb2.Video{}, 141 Ext: json.RawMessage(`{"bidder":{"kadfloor":"0.13"}}`), 142 }, 143 }, 144 expectedBidfloor: 0.13, 145 }, 146 { 147 name: "kadfloor string set with whitespace", 148 args: args{ 149 imp: &openrtb2.Imp{ 150 BidFloor: 0.12, 151 Video: &openrtb2.Video{}, 152 Ext: json.RawMessage(`{"bidder":{"kadfloor":" \t 0.13 "}}`), 153 }, 154 }, 155 expectedBidfloor: 0.13, 156 }, 157 } 158 for _, tt := range tests { 159 t.Run(tt.name, func(t *testing.T) { 160 receivedWrapperExt, receivedPublisherId, err := parseImpressionObject(tt.args.imp, tt.args.extractWrapperExtFromImp, tt.args.extractPubIDFromImp) 161 assert.Equal(t, tt.wantErr, err != nil) 162 assert.Equal(t, tt.expectedWrapperExt, receivedWrapperExt) 163 assert.Equal(t, tt.expectedPublisherId, receivedPublisherId) 164 assert.Equal(t, tt.expectedBidfloor, tt.args.imp.BidFloor) 165 }) 166 } 167 } 168 169 func TestExtractPubmaticExtFromRequest(t *testing.T) { 170 type args struct { 171 request *openrtb2.BidRequest 172 } 173 tests := []struct { 174 name string 175 args args 176 expectedReqExt extRequestAdServer 177 wantErr bool 178 }{ 179 { 180 name: "nil request", 181 args: args{ 182 request: nil, 183 }, 184 wantErr: false, 185 }, 186 { 187 name: "nil req.ext", 188 args: args{ 189 request: &openrtb2.BidRequest{Ext: nil}, 190 }, 191 wantErr: false, 192 }, 193 { 194 name: "Pubmatic wrapper ext missing/empty (empty bidderparms)", 195 args: args{ 196 request: &openrtb2.BidRequest{ 197 Ext: json.RawMessage(`{"prebid":{"bidderparams":{}}}`), 198 }, 199 }, 200 expectedReqExt: extRequestAdServer{ 201 ExtRequest: openrtb_ext.ExtRequest{ 202 Prebid: openrtb_ext.ExtRequestPrebid{ 203 BidderParams: json.RawMessage("{}"), 204 }, 205 }, 206 }, 207 wantErr: false, 208 }, 209 { 210 name: "Only Pubmatic wrapper ext present", 211 args: args{ 212 request: &openrtb2.BidRequest{ 213 Ext: json.RawMessage(`{"prebid":{"bidderparams":{"wrapper":{"profile":123,"version":456}}}}`), 214 }, 215 }, 216 expectedReqExt: extRequestAdServer{ 217 Wrapper: &pubmaticWrapperExt{ProfileID: 123, VersionID: 456}, 218 ExtRequest: openrtb_ext.ExtRequest{ 219 Prebid: openrtb_ext.ExtRequestPrebid{ 220 BidderParams: json.RawMessage(`{"wrapper":{"profile":123,"version":456}}`), 221 }, 222 }, 223 }, 224 wantErr: false, 225 }, 226 { 227 name: "Invalid Pubmatic wrapper ext", 228 args: args{ 229 request: &openrtb2.BidRequest{ 230 Ext: json.RawMessage(`{"prebid":{"bidderparams":"}}}`), 231 }, 232 }, 233 wantErr: true, 234 }, 235 { 236 name: "Valid Pubmatic acat ext", 237 args: args{ 238 request: &openrtb2.BidRequest{ 239 Ext: json.RawMessage(`{"prebid":{"bidderparams":{"acat":[" drg \t","dlu","ssr"],"wrapper":{"profile":123,"version":456}}}}`), 240 }, 241 }, 242 expectedReqExt: extRequestAdServer{ 243 Wrapper: &pubmaticWrapperExt{ProfileID: 123, VersionID: 456}, 244 Acat: []string{"drg", "dlu", "ssr"}, 245 ExtRequest: openrtb_ext.ExtRequest{ 246 Prebid: openrtb_ext.ExtRequestPrebid{ 247 BidderParams: json.RawMessage(`{"acat":[" drg \t","dlu","ssr"],"wrapper":{"profile":123,"version":456}}`), 248 }, 249 }, 250 }, 251 wantErr: false, 252 }, 253 { 254 name: "Invalid Pubmatic acat ext", 255 args: args{ 256 request: &openrtb2.BidRequest{ 257 Ext: json.RawMessage(`{"prebid":{"bidderparams":{"acat":[1,3,4],"wrapper":{"profile":123,"version":456}}}}`), 258 }, 259 }, 260 expectedReqExt: extRequestAdServer{ 261 Wrapper: &pubmaticWrapperExt{ProfileID: 123, VersionID: 456}, 262 ExtRequest: openrtb_ext.ExtRequest{ 263 Prebid: openrtb_ext.ExtRequestPrebid{ 264 BidderParams: json.RawMessage(`{"acat":[1,3,4],"wrapper":{"profile":123,"version":456}}`), 265 }, 266 }, 267 }, 268 wantErr: true, 269 }, 270 { 271 name: "Valid Pubmatic marketplace ext", 272 args: args{ 273 request: &openrtb2.BidRequest{ 274 Ext: json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"pubmatic":{"enabled":true,"allowedbiddercodes":["groupm"]}}},"bidderparams":{"wrapper":{"profile":123,"version":456}}}}`), 275 }, 276 }, 277 expectedReqExt: extRequestAdServer{ 278 Marketplace: &marketplaceReqExt{AllowedBidders: []string{"pubmatic", "groupm"}}, 279 Wrapper: &pubmaticWrapperExt{ProfileID: 123, VersionID: 456}, 280 ExtRequest: openrtb_ext.ExtRequest{ 281 Prebid: openrtb_ext.ExtRequestPrebid{ 282 BidderParams: json.RawMessage(`{"wrapper":{"profile":123,"version":456}}`), 283 AlternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{Enabled: true, Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{"pubmatic": {Enabled: true, AllowedBidderCodes: []string{"groupm"}}}}, 284 }, 285 }, 286 }, 287 wantErr: false, 288 }, 289 } 290 for _, tt := range tests { 291 t.Run(tt.name, func(t *testing.T) { 292 gotReqExt, err := extractPubmaticExtFromRequest(tt.args.request) 293 assert.Equal(t, tt.wantErr, err != nil) 294 assert.Equal(t, tt.expectedReqExt, gotReqExt) 295 }) 296 } 297 } 298 299 func TestPubmaticAdapter_MakeRequests(t *testing.T) { 300 type fields struct { 301 URI string 302 } 303 type args struct { 304 request *openrtb2.BidRequest 305 reqInfo *adapters.ExtraRequestInfo 306 } 307 tests := []struct { 308 name string 309 fields fields 310 args args 311 expectedReqData []*adapters.RequestData 312 wantErr bool 313 }{ 314 // Happy paths covered by TestJsonSamples() 315 // Covering only error scenarios here 316 { 317 name: "invalid bidderparams", 318 args: args{ 319 request: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{"bidderparams":{"wrapper":"123"}}}`)}, 320 }, 321 wantErr: true, 322 }, 323 } 324 for _, tt := range tests { 325 t.Run(tt.name, func(t *testing.T) { 326 a := &PubmaticAdapter{ 327 URI: tt.fields.URI, 328 } 329 gotReqData, gotErr := a.MakeRequests(tt.args.request, tt.args.reqInfo) 330 assert.Equal(t, tt.wantErr, len(gotErr) != 0) 331 assert.Equal(t, tt.expectedReqData, gotReqData) 332 }) 333 } 334 } 335 336 func TestPubmaticAdapter_MakeBids(t *testing.T) { 337 type fields struct { 338 URI string 339 } 340 type args struct { 341 internalRequest *openrtb2.BidRequest 342 externalRequest *adapters.RequestData 343 response *adapters.ResponseData 344 } 345 tests := []struct { 346 name string 347 fields fields 348 args args 349 wantErr []error 350 wantResp *adapters.BidderResponse 351 }{ 352 { 353 name: "happy path, valid response with all bid params", 354 args: args{ 355 response: &adapters.ResponseData{ 356 StatusCode: http.StatusOK, 357 Body: []byte(`{"id": "test-request-id", "seatbid":[{"seat": "958", "bid":[{"id": "7706636740145184841", "impid": "test-imp-id", "price": 0.500000, "adid": "29681110", "adm": "some-test-ad", "adomain":["pubmatic.com"], "crid": "29681110", "h": 250, "w": 300, "dealid": "testdeal", "ext":{"dspid": 6, "deal_channel": 1, "prebiddealpriority": 1}}]}], "bidid": "5778926625248726496", "cur": "USD"}`), 358 }, 359 }, 360 wantErr: nil, 361 wantResp: &adapters.BidderResponse{ 362 Bids: []*adapters.TypedBid{ 363 { 364 Bid: &openrtb2.Bid{ 365 ID: "7706636740145184841", 366 ImpID: "test-imp-id", 367 Price: 0.500000, 368 AdID: "29681110", 369 AdM: "some-test-ad", 370 ADomain: []string{"pubmatic.com"}, 371 CrID: "29681110", 372 H: 250, 373 W: 300, 374 DealID: "testdeal", 375 Ext: json.RawMessage(`{"dspid": 6, "deal_channel": 1, "prebiddealpriority": 1}`), 376 }, 377 DealPriority: 1, 378 BidType: openrtb_ext.BidTypeBanner, 379 BidVideo: &openrtb_ext.ExtBidPrebidVideo{}, 380 }, 381 }, 382 Currency: "USD", 383 }, 384 }, 385 { 386 name: "ignore invalid prebiddealpriority", 387 args: args{ 388 response: &adapters.ResponseData{ 389 StatusCode: http.StatusOK, 390 Body: []byte(`{"id": "test-request-id", "seatbid":[{"seat": "958", "bid":[{"id": "7706636740145184841", "impid": "test-imp-id", "price": 0.500000, "adid": "29681110", "adm": "some-test-ad", "adomain":["pubmatic.com"], "crid": "29681110", "h": 250, "w": 300, "dealid": "testdeal", "ext":{"dspid": 6, "deal_channel": 1, "prebiddealpriority": -1}}]}], "bidid": "5778926625248726496", "cur": "USD"}`), 391 }, 392 }, 393 wantErr: nil, 394 wantResp: &adapters.BidderResponse{ 395 Bids: []*adapters.TypedBid{ 396 { 397 Bid: &openrtb2.Bid{ 398 ID: "7706636740145184841", 399 ImpID: "test-imp-id", 400 Price: 0.500000, 401 AdID: "29681110", 402 AdM: "some-test-ad", 403 ADomain: []string{"pubmatic.com"}, 404 CrID: "29681110", 405 H: 250, 406 W: 300, 407 DealID: "testdeal", 408 Ext: json.RawMessage(`{"dspid": 6, "deal_channel": 1, "prebiddealpriority": -1}`), 409 }, 410 BidType: openrtb_ext.BidTypeBanner, 411 BidVideo: &openrtb_ext.ExtBidPrebidVideo{}, 412 }, 413 }, 414 Currency: "USD", 415 }, 416 }, 417 } 418 for _, tt := range tests { 419 t.Run(tt.name, func(t *testing.T) { 420 a := &PubmaticAdapter{ 421 URI: tt.fields.URI, 422 } 423 gotResp, gotErr := a.MakeBids(tt.args.internalRequest, tt.args.externalRequest, tt.args.response) 424 assert.Equal(t, tt.wantErr, gotErr, gotErr) 425 assert.Equal(t, tt.wantResp, gotResp) 426 }) 427 } 428 } 429 430 func Test_getAlternateBidderCodesFromRequest(t *testing.T) { 431 type args struct { 432 bidRequest *openrtb2.BidRequest 433 } 434 tests := []struct { 435 name string 436 args args 437 want []string 438 }{ 439 { 440 name: "request.ext nil", 441 args: args{ 442 bidRequest: &openrtb2.BidRequest{Ext: nil}, 443 }, 444 want: nil, 445 }, 446 { 447 name: "alternatebiddercodes not present in request.ext", 448 args: args{ 449 bidRequest: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{}}`)}, 450 }, 451 want: nil, 452 }, 453 { 454 name: "alternatebiddercodes feature disabled", 455 args: args{ 456 bidRequest: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":false,"bidders":{"pubmatic":{"enabled":true,"allowedbiddercodes":["groupm"]}}}}}`)}, 457 }, 458 want: []string{"pubmatic"}, 459 }, 460 { 461 name: "alternatebiddercodes disabled at bidder level", 462 args: args{ 463 bidRequest: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"pubmatic":{"enabled":false,"allowedbiddercodes":["groupm"]}}}}}`)}, 464 }, 465 want: []string{"pubmatic"}, 466 }, 467 { 468 name: "alternatebiddercodes list not defined", 469 args: args{ 470 bidRequest: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"pubmatic":{"enabled":true}}}}}`)}, 471 }, 472 want: []string{"all"}, 473 }, 474 { 475 name: "wildcard in alternatebiddercodes list", 476 args: args{ 477 bidRequest: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"pubmatic":{"enabled":true,"allowedbiddercodes":["*"]}}}}}`)}, 478 }, 479 want: []string{"all"}, 480 }, 481 { 482 name: "empty alternatebiddercodes list", 483 args: args{ 484 bidRequest: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"pubmatic":{"enabled":true,"allowedbiddercodes":[]}}}}}`)}, 485 }, 486 want: []string{"pubmatic"}, 487 }, 488 { 489 name: "only groupm in alternatebiddercodes allowed", 490 args: args{ 491 bidRequest: &openrtb2.BidRequest{Ext: json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"pubmatic":{"enabled":true,"allowedbiddercodes":["groupm"]}}}}}`)}, 492 }, 493 want: []string{"pubmatic", "groupm"}, 494 }, 495 } 496 for _, tt := range tests { 497 t.Run(tt.name, func(t *testing.T) { 498 var reqExt *openrtb_ext.ExtRequest 499 if len(tt.args.bidRequest.Ext) > 0 { 500 err := json.Unmarshal(tt.args.bidRequest.Ext, &reqExt) 501 if err != nil { 502 t.Errorf("getAlternateBidderCodesFromRequest() = %v", err) 503 } 504 } 505 506 got := getAlternateBidderCodesFromRequestExt(reqExt) 507 assert.ElementsMatch(t, got, tt.want, tt.name) 508 }) 509 } 510 } 511 512 func TestPopulateFirstPartyDataImpAttributes(t *testing.T) { 513 type args struct { 514 data json.RawMessage 515 impExtMap map[string]interface{} 516 } 517 tests := []struct { 518 name string 519 args args 520 expectedImpExt map[string]interface{} 521 }{ 522 { 523 name: "Only Targeting present in imp.ext.data", 524 args: args{ 525 data: json.RawMessage(`{"sport":["rugby","cricket"]}`), 526 impExtMap: map[string]interface{}{}, 527 }, 528 expectedImpExt: map[string]interface{}{ 529 "key_val": "sport=rugby,cricket", 530 }, 531 }, 532 { 533 name: "Targeting and adserver object present in imp.ext.data", 534 args: args{ 535 data: json.RawMessage(`{"adserver": {"name": "gam","adslot": "/1111/home"},"pbadslot": "/2222/home","sport":["rugby","cricket"]}`), 536 impExtMap: map[string]interface{}{}, 537 }, 538 expectedImpExt: map[string]interface{}{ 539 "dfp_ad_unit_code": "/1111/home", 540 "key_val": "sport=rugby,cricket", 541 }, 542 }, 543 { 544 name: "Targeting and pbadslot key present in imp.ext.data ", 545 args: args{ 546 data: json.RawMessage(`{"pbadslot": "/2222/home","sport":["rugby","cricket"]}`), 547 impExtMap: map[string]interface{}{}, 548 }, 549 expectedImpExt: map[string]interface{}{ 550 "dfp_ad_unit_code": "/2222/home", 551 "key_val": "sport=rugby,cricket", 552 }, 553 }, 554 { 555 name: "Targeting and Invalid Adserver object in imp.ext.data", 556 args: args{ 557 data: json.RawMessage(`{"adserver": "invalid","sport":["rugby","cricket"]}`), 558 impExtMap: map[string]interface{}{}, 559 }, 560 expectedImpExt: map[string]interface{}{ 561 "key_val": "sport=rugby,cricket", 562 }, 563 }, 564 { 565 name: "key_val already present in imp.ext.data", 566 args: args{ 567 data: json.RawMessage(`{"sport":["rugby","cricket"]}`), 568 impExtMap: map[string]interface{}{ 569 "key_val": "k1=v1|k2=v2", 570 }, 571 }, 572 expectedImpExt: map[string]interface{}{ 573 "key_val": "k1=v1|k2=v2|sport=rugby,cricket", 574 }, 575 }, 576 { 577 name: "int data present in imp.ext.data", 578 args: args{ 579 data: json.RawMessage(`{"age": 25}`), 580 impExtMap: map[string]interface{}{}, 581 }, 582 expectedImpExt: map[string]interface{}{ 583 "key_val": "age=25", 584 }, 585 }, 586 { 587 name: "float data present in imp.ext.data", 588 args: args{ 589 data: json.RawMessage(`{"floor": 0.15}`), 590 impExtMap: map[string]interface{}{}, 591 }, 592 expectedImpExt: map[string]interface{}{ 593 "key_val": "floor=0.15", 594 }, 595 }, 596 { 597 name: "bool data present in imp.ext.data", 598 args: args{ 599 data: json.RawMessage(`{"k1": true}`), 600 impExtMap: map[string]interface{}{}, 601 }, 602 expectedImpExt: map[string]interface{}{ 603 "key_val": "k1=true", 604 }, 605 }, 606 { 607 name: "imp.ext.data is not present", 608 args: args{ 609 data: nil, 610 impExtMap: map[string]interface{}{}, 611 }, 612 expectedImpExt: map[string]interface{}{}, 613 }, 614 { 615 name: "string with spaces present in imp.ext.data", 616 args: args{ 617 data: json.RawMessage(`{" category ": " cinema "}`), 618 impExtMap: map[string]interface{}{}, 619 }, 620 expectedImpExt: map[string]interface{}{ 621 "key_val": "category=cinema", 622 }, 623 }, 624 { 625 name: "string array with spaces present in imp.ext.data", 626 args: args{ 627 data: json.RawMessage(`{" country\t": [" India", "\tChina "]}`), 628 impExtMap: map[string]interface{}{}, 629 }, 630 expectedImpExt: map[string]interface{}{ 631 "key_val": "country=India,China", 632 }, 633 }, 634 { 635 name: "Invalid data present in imp.ext.data", 636 args: args{ 637 data: json.RawMessage(`{"country": [1, "India"],"category":"movies"}`), 638 impExtMap: map[string]interface{}{}, 639 }, 640 expectedImpExt: map[string]interface{}{ 641 "key_val": "category=movies", 642 }, 643 }, 644 } 645 for _, tt := range tests { 646 t.Run(tt.name, func(t *testing.T) { 647 populateFirstPartyDataImpAttributes(tt.args.data, tt.args.impExtMap) 648 assert.Equal(t, tt.expectedImpExt, tt.args.impExtMap) 649 }) 650 } 651 } 652 653 func TestPopulateFirstPartyDataImpAttributesForMultipleAttributes(t *testing.T) { 654 impExtMap := map[string]interface{}{ 655 "key_val": "k1=v1|k2=v2", 656 } 657 data := json.RawMessage(`{"sport":["rugby","cricket"],"pageType":"article","age":30,"floor":1.25}`) 658 expectedKeyValArr := []string{"age=30", "floor=1.25", "k1=v1", "k2=v2", "pageType=article", "sport=rugby,cricket"} 659 660 populateFirstPartyDataImpAttributes(data, impExtMap) 661 662 //read dctr value and split on "|" for comparison 663 actualKeyValArr := strings.Split(impExtMap[dctrKeyName].(string), "|") 664 sort.Strings(actualKeyValArr) 665 assert.Equal(t, expectedKeyValArr, actualKeyValArr) 666 } 667 668 func TestGetStringArray(t *testing.T) { 669 tests := []struct { 670 name string 671 input []interface{} 672 output []string 673 }{ 674 { 675 name: "Valid String Array", 676 input: append(make([]interface{}, 0), "hello", "world"), 677 output: []string{"hello", "world"}, 678 }, 679 { 680 name: "Invalid String Array", 681 input: append(make([]interface{}, 0), 1, 2), 682 output: nil, 683 }, 684 } 685 for _, tt := range tests { 686 t.Run(tt.name, func(t *testing.T) { 687 got := getStringArray(tt.input) 688 assert.Equal(t, tt.output, got) 689 }) 690 } 691 } 692 693 func TestGetMapFromJSON(t *testing.T) { 694 tests := []struct { 695 name string 696 input json.RawMessage 697 output map[string]interface{} 698 }{ 699 { 700 name: "Valid JSON", 701 input: json.RawMessage(`{"buyid":"testBuyId"}`), 702 output: map[string]interface{}{ 703 "buyid": "testBuyId", 704 }, 705 }, 706 { 707 name: "Invalid JSON", 708 input: json.RawMessage(`{"buyid":}`), 709 output: nil, 710 }, 711 } 712 for _, tt := range tests { 713 t.Run(tt.name, func(t *testing.T) { 714 got := getMapFromJSON(tt.input) 715 assert.Equal(t, tt.output, got) 716 }) 717 } 718 }