github.com/prebid/prebid-server/v2@v2.18.0/floors/rule_test.go (about) 1 package floors 2 3 import ( 4 "encoding/json" 5 "errors" 6 "testing" 7 8 "github.com/prebid/openrtb/v20/openrtb2" 9 "github.com/prebid/prebid-server/v2/currency" 10 "github.com/prebid/prebid-server/v2/openrtb_ext" 11 "github.com/prebid/prebid-server/v2/util/ptrutil" 12 "github.com/stretchr/testify/assert" 13 ) 14 15 func TestPrepareRuleCombinations(t *testing.T) { 16 testCases := []struct { 17 name string 18 in []string 19 del string 20 exp []string 21 }{ 22 { 23 name: "Schema items, n = 1", 24 in: []string{"A"}, 25 del: "|", 26 exp: []string{ 27 "a", 28 "*", 29 }, 30 }, 31 { 32 name: "Schema items, n = 2", 33 in: []string{"A", "B"}, 34 del: "|", 35 exp: []string{ 36 "a|b", 37 "a|*", 38 "*|b", 39 "*|*", 40 }, 41 }, 42 { 43 name: "Schema items, n = 3", 44 in: []string{"A", "B", "C"}, 45 del: "|", 46 exp: []string{ 47 "a|b|c", 48 "a|b|*", 49 "a|*|c", 50 "*|b|c", 51 "a|*|*", 52 "*|b|*", 53 "*|*|c", 54 "*|*|*", 55 }, 56 }, 57 { 58 name: "Schema items, n = 4", 59 in: []string{"A", "B", "C", "D"}, 60 del: "|", 61 exp: []string{ 62 "a|b|c|d", 63 "a|b|c|*", 64 "a|b|*|d", 65 "a|*|c|d", 66 "*|b|c|d", 67 "a|b|*|*", 68 "a|*|c|*", 69 "a|*|*|d", 70 "*|b|c|*", 71 "*|b|*|d", 72 "*|*|c|d", 73 "a|*|*|*", 74 "*|b|*|*", 75 "*|*|c|*", 76 "*|*|*|d", 77 "*|*|*|*", 78 }, 79 }, 80 { 81 name: "Schema items, n = 1 with wildcards", 82 in: []string{"*"}, 83 del: "|", 84 exp: []string{ 85 "*", 86 }, 87 }, 88 { 89 name: "Schema items, n = 2 with wildcard at index = 0", 90 in: []string{"*", "B"}, 91 del: "|", 92 exp: []string{ 93 "*|b", 94 "*|*", 95 }, 96 }, 97 { 98 name: "Schema items, n = 2 with wildcards at index = 1", 99 in: []string{"A", "*"}, 100 del: "|", 101 exp: []string{ 102 "a|*", 103 "*|*", 104 }, 105 }, 106 107 { 108 name: "Schema items, n = 2 wildcards at index = 0,1", 109 in: []string{"*", "*"}, 110 del: "|", 111 exp: []string{ 112 "*|*", 113 }, 114 }, 115 116 { 117 name: "Schema items, n = 3 wildcard at index = 0", 118 in: []string{"*", "B", "C"}, 119 del: "|", 120 exp: []string{ 121 "*|b|c", 122 "*|b|*", 123 "*|*|c", 124 "*|*|*", 125 }, 126 }, 127 { 128 name: "Schema items, n = 3 wildcard at index = 1", 129 in: []string{"A", "*", "C"}, 130 del: "|", 131 exp: []string{ 132 "a|*|c", 133 "a|*|*", 134 "*|*|c", 135 "*|*|*", 136 }, 137 }, 138 { 139 name: "Schema items, n = 3 with wildcard at index = 2", 140 in: []string{"A", "B", "*"}, 141 del: "|", 142 exp: []string{ 143 "a|b|*", 144 "a|*|*", 145 "*|b|*", 146 "*|*|*", 147 }, 148 }, 149 { 150 name: "Schema items, n = 3 with wildcard at index = 0,2", 151 in: []string{"*", "B", "*"}, 152 del: "|", 153 exp: []string{ 154 "*|b|*", 155 "*|*|*", 156 }, 157 }, 158 { 159 name: "Schema items, n = 3 with wildcard at index = 0,1", 160 in: []string{"*", "*", "C"}, 161 del: "|", 162 exp: []string{ 163 "*|*|c", 164 "*|*|*", 165 }, 166 }, 167 { 168 name: "Schema items, n = 3 with wildcard at index = 1,2", 169 in: []string{"A", "*", "*"}, 170 del: "|", 171 exp: []string{ 172 "a|*|*", 173 "*|*|*", 174 }, 175 }, 176 } 177 for _, tc := range testCases { 178 t.Run(tc.name, func(t *testing.T) { 179 act := prepareRuleCombinations(tc.in, tc.del) 180 assert.Equal(t, tc.exp, act, tc.name) 181 }) 182 } 183 } 184 185 func TestUpdateImpExtWithFloorDetails(t *testing.T) { 186 testCases := []struct { 187 name string 188 matchedRule string 189 floorRuleVal float64 190 floorVal float64 191 imp *openrtb_ext.ImpWrapper 192 expected json.RawMessage 193 }{ 194 { 195 name: "Nil ImpExt", 196 matchedRule: "test|123|xyz", 197 floorRuleVal: 5.5, 198 floorVal: 5.5, 199 imp: &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{ID: "1234", Video: &openrtb2.Video{W: ptrutil.ToPtr[int64](300), H: ptrutil.ToPtr[int64](250)}}}, 200 expected: []byte(`{"prebid":{"floors":{"floorrule":"test|123|xyz","floorrulevalue":5.5,"floorvalue":5.5}}}`), 201 }, 202 { 203 name: "Empty ImpExt", 204 matchedRule: "test|123|xyz", 205 floorRuleVal: 5.5, 206 floorVal: 5.5, 207 imp: &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{ID: "1234", Video: &openrtb2.Video{W: ptrutil.ToPtr[int64](300), H: ptrutil.ToPtr[int64](250)}, Ext: json.RawMessage{}}}, 208 expected: []byte(`{"prebid":{"floors":{"floorrule":"test|123|xyz","floorrulevalue":5.5,"floorvalue":5.5}}}`), 209 }, 210 { 211 name: "With prebid Ext", 212 matchedRule: "banner|www.test.com|*", 213 floorRuleVal: 5.5, 214 floorVal: 15.5, 215 imp: &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{ID: "1234", Video: &openrtb2.Video{W: ptrutil.ToPtr[int64](300), H: ptrutil.ToPtr[int64](250)}, Ext: []byte(`{"prebid": {"test": true}}`)}}, 216 expected: []byte(`{"prebid":{"floors":{"floorrule":"banner|www.test.com|*","floorrulevalue":5.5,"floorvalue":15.5}}}`), 217 }, 218 } 219 for _, tc := range testCases { 220 t.Run(tc.name, func(t *testing.T) { 221 updateImpExtWithFloorDetails(tc.imp, tc.matchedRule, tc.floorRuleVal, tc.floorVal) 222 _ = tc.imp.RebuildImp() 223 if tc.imp.Ext != nil { 224 assert.Equal(t, tc.imp.Ext, tc.expected, tc.name) 225 } 226 }) 227 } 228 } 229 230 func TestCreateRuleKeys(t *testing.T) { 231 testCases := []struct { 232 name string 233 floorSchema openrtb_ext.PriceFloorSchema 234 request *openrtb2.BidRequest 235 out []string 236 }{ 237 { 238 name: "CreateRule with banner mediatype, size and domain", 239 request: &openrtb2.BidRequest{ 240 Site: &openrtb2.Site{ 241 Domain: "www.test.com", 242 }, 243 Imp: []openrtb2.Imp{{ID: "1234", Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}}}, 244 Ext: json.RawMessage(`{"prebid": { "floors": {"data": {"currency": "USD","skipRate": 0,"schema": {"fields": [ "mediaType", "size", "domain" ] },"values": { "banner|300x250|www.website.com": 1.01, "banner|300x250|*": 2.01, "banner|300x600|www.website.com": 3.01, "banner|300x600|*": 4.01, "banner|728x90|www.website.com": 5.01, "banner|728x90|*": 6.01, "banner|*|www.website.com": 7.01, "banner|*|*": 8.01, "*|300x250|www.website.com": 9.01, "*|300x250|*": 10.01, "*|300x600|www.website.com": 11.01, "*|300x600|*": 12.01, "*|728x90|www.website.com": 13.01, "*|728x90|*": 14.01, "*|*|www.website.com": 15.01, "*|*|*": 16.01 }, "default": 1}}}}`), 245 }, 246 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"mediaType", "size", "domain"}}, 247 out: []string{"banner", "300x250", "www.test.com"}, 248 }, 249 { 250 name: "CreateRule with video mediatype, size and domain", 251 request: &openrtb2.BidRequest{ 252 Site: &openrtb2.Site{ 253 Domain: "www.test.com", 254 }, 255 Imp: []openrtb2.Imp{{ID: "1234", Video: &openrtb2.Video{W: ptrutil.ToPtr[int64](640), H: ptrutil.ToPtr[int64](480), Placement: 1}}}, 256 }, 257 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"mediaType", "size", "domain"}}, 258 out: []string{"video", "640x480", "www.test.com"}, 259 }, 260 { 261 name: "CreateRule with video mediatype, size and domain", 262 request: &openrtb2.BidRequest{ 263 Site: &openrtb2.Site{ 264 Domain: "www.test.com", 265 }, 266 Imp: []openrtb2.Imp{{ID: "1234", Video: &openrtb2.Video{W: ptrutil.ToPtr[int64](300), H: ptrutil.ToPtr[int64](250), Placement: 2}}}, 267 }, 268 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"mediaType", "size", "domain"}}, 269 out: []string{"video-outstream", "300x250", "www.test.com"}, 270 }, 271 { 272 name: "CreateRule with audio mediatype, adUnitCode and domain", 273 request: &openrtb2.BidRequest{ 274 Site: &openrtb2.Site{ 275 Domain: "www.test.com", 276 }, 277 Imp: []openrtb2.Imp{{ID: "1234", TagID: "tag123", Audio: &openrtb2.Audio{MaxDuration: 300}}}, 278 }, 279 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"mediaType", "adUnitCode", "siteDomain"}}, 280 out: []string{"audio", "tag123", "www.test.com"}, 281 }, 282 { 283 name: "CreateRule with audio mediatype, adUnitCode=* and domain", 284 request: &openrtb2.BidRequest{ 285 Site: &openrtb2.Site{ 286 Domain: "www.test.com", 287 }, 288 Imp: []openrtb2.Imp{{ID: "1234", Audio: &openrtb2.Audio{MaxDuration: 300}}}, 289 }, 290 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"mediaType", "adUnitCode", "siteDomain"}}, 291 out: []string{"audio", "*", "www.test.com"}, 292 }, 293 { 294 name: "CreateRule with native mediatype, bundle and domain", 295 request: &openrtb2.BidRequest{ 296 App: &openrtb2.App{ 297 Domain: "www.test.com", 298 Bundle: "bundle123", 299 }, 300 Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}}}, 301 }, 302 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"mediaType", "bundle", "siteDomain"}}, 303 out: []string{"native", "bundle123", "www.test.com"}, 304 }, 305 { 306 name: "CreateRule with native, banner mediatype, bundle and domain", 307 request: &openrtb2.BidRequest{ 308 App: &openrtb2.App{ 309 Domain: "www.test.com", 310 Bundle: "bundle123", 311 }, 312 Imp: []openrtb2.Imp{{ID: "1234", Audio: &openrtb2.Audio{MaxDuration: 300}, Native: &openrtb2.Native{Request: "Test"}}}, 313 }, 314 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"mediaType", "bundle", "siteDomain"}}, 315 out: []string{"*", "bundle123", "www.test.com"}, 316 }, 317 { 318 name: "CreateRule with channel, country, deviceType", 319 request: &openrtb2.BidRequest{ 320 App: &openrtb2.App{ 321 Publisher: &openrtb2.Publisher{ 322 Domain: "www.test.com", 323 }, 324 Bundle: "bundle123", 325 }, 326 Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}, UA: "tablet"}, 327 Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}}}, 328 Ext: json.RawMessage(`{"prebid": {"channel": {"name": "chName","version": "ver1"}}}`), 329 }, 330 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"channel", "country", "deviceType"}}, 331 out: []string{"chName", "USA", "tablet"}, 332 }, 333 { 334 name: "CreateRule with channel, country, deviceType=tablet", 335 request: &openrtb2.BidRequest{ 336 App: &openrtb2.App{ 337 Publisher: &openrtb2.Publisher{ 338 Domain: "www.test.com", 339 }, 340 Bundle: "bundle123", 341 }, 342 Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}, UA: "Windows NT touch"}, 343 Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}}}, 344 Ext: json.RawMessage(`{"prebid": {"channel": {"name": "chName","version": "ver1"}}}`), 345 }, 346 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"channel", "country", "deviceType"}}, 347 out: []string{"chName", "USA", "tablet"}, 348 }, 349 { 350 name: "CreateRule with channel, country, deviceType=desktop", 351 request: &openrtb2.BidRequest{ 352 App: &openrtb2.App{ 353 Publisher: &openrtb2.Publisher{ 354 Domain: "www.test.com", 355 }, 356 Bundle: "bundle123", 357 }, 358 Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}, UA: "Windows NT"}, 359 Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}}}, 360 Ext: json.RawMessage(`{"prebid": {"channel": {"name": "chName","version": "ver1"}}}`), 361 }, 362 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"channel", "country", "deviceType"}}, 363 out: []string{"chName", "USA", "desktop"}, 364 }, 365 { 366 name: "CreateRule with channel, country, deviceType=desktop", 367 request: &openrtb2.BidRequest{ 368 App: &openrtb2.App{ 369 Publisher: &openrtb2.Publisher{ 370 Domain: "www.test.com", 371 }, 372 Bundle: "bundle123", 373 }, 374 Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}, UA: "Windows NT"}, 375 Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}}}, 376 Ext: json.RawMessage(`{"prebid": {"channel": {"name": "chName","version": "ver1"}}}`), 377 }, 378 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"channel", "country", "deviceType"}}, 379 out: []string{"chName", "USA", "desktop"}, 380 }, 381 { 382 name: "CreateRule with channel, size, deviceType=desktop", 383 request: &openrtb2.BidRequest{ 384 App: &openrtb2.App{ 385 Publisher: &openrtb2.Publisher{ 386 Domain: "www.test.com", 387 }, 388 Bundle: "bundle123", 389 }, 390 Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}, UA: "SomeDevice"}, 391 Imp: []openrtb2.Imp{{ID: "1234", Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 100, H: 200}, {W: 200, H: 300}}}}}, 392 Ext: json.RawMessage(`{"prebid": {"test": "1}}`), 393 }, 394 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"channel", "size", "deviceType"}}, 395 out: []string{"*", "*", "desktop"}, 396 }, 397 { 398 name: "CreateRule with pubDomain, country, deviceType", 399 request: &openrtb2.BidRequest{ 400 App: &openrtb2.App{ 401 Publisher: &openrtb2.Publisher{ 402 Domain: "www.test.com", 403 }, 404 Bundle: "bundle123", 405 }, 406 Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}, UA: "Phone"}, 407 Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}}}, 408 Ext: json.RawMessage(`{"prebid": {"channel": {"name": "chName","version": "ver1"}}}`), 409 }, 410 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"pubDomain", "country", "deviceType"}}, 411 out: []string{"www.test.com", "USA", "phone"}, 412 }, 413 { 414 name: "CreateRule with pubDomain, gptSlot, deviceType", 415 request: &openrtb2.BidRequest{ 416 Site: &openrtb2.Site{ 417 Publisher: &openrtb2.Publisher{ 418 Domain: "www.test.com", 419 }, 420 }, 421 Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}}, 422 Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}, 423 Ext: json.RawMessage(`{"data": {"adserver": {"name": "gam","adslot": "adslot123"}, "pbadslot": "pbadslot123"}}`), 424 }}, 425 Ext: json.RawMessage(`{"prebid": {"channel": {"name": "chName","version": "ver1"}}}`), 426 }, 427 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"pubDomain", "gptSlot", "deviceType"}}, 428 out: []string{"www.test.com", "adslot123", "*"}, 429 }, 430 { 431 name: "CreateRule with pubDomain, gptSlot, deviceType", 432 request: &openrtb2.BidRequest{ 433 Site: &openrtb2.Site{ 434 Publisher: &openrtb2.Publisher{ 435 Domain: "www.test.com", 436 }, 437 }, 438 Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}}, 439 Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}, 440 Ext: json.RawMessage(`{"data": {"adserver": {"name": "test","adslot": "adslot123"}, "pbadslot": "pbadslot123"}}`), 441 }}, 442 Ext: json.RawMessage(`{"prebid": {"channel": {"name": "chName","version": "ver1"}}}`), 443 }, 444 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"pubDomain", "gptSlot", "deviceType"}}, 445 out: []string{"www.test.com", "pbadslot123", "*"}, 446 }, 447 { 448 name: "CreateRule with domain, adUnitCode, channel", 449 request: &openrtb2.BidRequest{ 450 App: &openrtb2.App{ 451 Publisher: &openrtb2.Publisher{ 452 Domain: "www.test.com", 453 }, 454 }, 455 Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}}, 456 Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}, 457 Ext: json.RawMessage(`{"data": {"adserver": {"name": "test","adslot": "adslot123"}, "pbadslot": "pbadslot123"}}`), 458 }}, 459 }, 460 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"domain", "adUnitCode", "channel"}}, 461 out: []string{"www.test.com", "pbadslot123", "*"}, 462 }, 463 { 464 name: "CreateRule with domain, adUnitCode, channel", 465 request: &openrtb2.BidRequest{ 466 App: &openrtb2.App{ 467 Publisher: &openrtb2.Publisher{ 468 Domain: "www.test.com", 469 }, 470 }, 471 Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}}, 472 Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}, 473 Ext: json.RawMessage(`{"gpid": "gpid_134"}`), 474 }}, 475 }, 476 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"domain", "adUnitCode", "channel"}}, 477 out: []string{"www.test.com", "gpid_134", "*"}, 478 }, 479 { 480 name: "CreateRule with domain, adUnitCode, channel", 481 request: &openrtb2.BidRequest{ 482 App: &openrtb2.App{ 483 Publisher: &openrtb2.Publisher{ 484 Domain: "www.test.com", 485 }, 486 }, 487 Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}}, 488 Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{}, Ext: json.RawMessage(`{"prebid": {"storedrequest": {"id": "storedid_123"}}}`)}}, 489 }, 490 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"domain", "adUnitCode", "channel"}}, 491 out: []string{"www.test.com", "storedid_123", "*"}, 492 }, 493 { 494 name: "CreateRule with domain, adUnitCode, channel", 495 request: &openrtb2.BidRequest{ 496 App: &openrtb2.App{ 497 Publisher: &openrtb2.Publisher{ 498 Domain: "www.test.com", 499 }, 500 }, 501 Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}}, 502 Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{}, Ext: json.RawMessage(`{"prebid": {"storedrequest": {"id": "storedid_123"}}}`)}}, 503 }, 504 floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"domain", "adUnitCode", "channel"}}, 505 out: []string{"www.test.com", "storedid_123", "*"}, 506 }, 507 } 508 for _, tc := range testCases { 509 t.Run(tc.name, func(t *testing.T) { 510 out := createRuleKey(tc.floorSchema, &openrtb_ext.RequestWrapper{BidRequest: tc.request}, &openrtb_ext.ImpWrapper{Imp: &tc.request.Imp[0]}) 511 assert.Equal(t, out, tc.out, tc.name) 512 }) 513 } 514 } 515 516 func TestShouldSkipFloors(t *testing.T) { 517 518 testCases := []struct { 519 name string 520 ModelGroupsSkipRate int 521 DataSkipRate int 522 RootSkipRate int 523 out bool 524 randomGen func(int) int 525 }{ 526 { 527 name: "ModelGroupsSkipRate=10 with skip = true", 528 ModelGroupsSkipRate: 10, 529 DataSkipRate: 0, 530 RootSkipRate: 0, 531 randomGen: func(i int) int { return 5 }, 532 out: true, 533 }, 534 { 535 name: "ModelGroupsSkipRate=100 with skip = true", 536 ModelGroupsSkipRate: 100, 537 DataSkipRate: 0, 538 RootSkipRate: 0, 539 randomGen: func(i int) int { return 5 }, 540 out: true, 541 }, 542 { 543 name: "ModelGroupsSkipRate=0 with skip = false", 544 ModelGroupsSkipRate: 0, 545 DataSkipRate: 0, 546 RootSkipRate: 0, 547 randomGen: func(i int) int { return 0 }, 548 out: false, 549 }, 550 { 551 name: "DataSkipRate=50 with with skip = true", 552 ModelGroupsSkipRate: 0, 553 DataSkipRate: 50, 554 RootSkipRate: 0, 555 randomGen: func(i int) int { return 40 }, 556 out: true, 557 }, 558 { 559 name: "RootSkipRate=50 with with skip = true", 560 ModelGroupsSkipRate: 0, 561 DataSkipRate: 0, 562 RootSkipRate: 60, 563 randomGen: func(i int) int { return 40 }, 564 out: true, 565 }, 566 { 567 name: "RootSkipRate=50 with with skip = false", 568 ModelGroupsSkipRate: 0, 569 DataSkipRate: 0, 570 RootSkipRate: 60, 571 randomGen: func(i int) int { return 70 }, 572 out: false, 573 }, 574 { 575 name: "RootSkipRate=100 with with skip = true", 576 ModelGroupsSkipRate: 0, 577 DataSkipRate: 0, 578 RootSkipRate: 100, 579 randomGen: func(i int) int { return 100 }, 580 out: true, 581 }, 582 } 583 for _, tc := range testCases { 584 t.Run(tc.name, func(t *testing.T) { 585 out := shouldSkipFloors(tc.ModelGroupsSkipRate, tc.DataSkipRate, tc.RootSkipRate, tc.randomGen) 586 assert.Equal(t, out, tc.out, tc.name) 587 }) 588 } 589 590 } 591 592 func TestSelectFloorModelGroup(t *testing.T) { 593 weightNilModelGroup := openrtb_ext.PriceFloorModelGroup{ModelWeight: nil} 594 weight01ModelGroup := openrtb_ext.PriceFloorModelGroup{ModelWeight: getIntPtr(1)} 595 weight25ModelGroup := openrtb_ext.PriceFloorModelGroup{ModelWeight: getIntPtr(25)} 596 weight50ModelGroup := openrtb_ext.PriceFloorModelGroup{ModelWeight: getIntPtr(50)} 597 598 testCases := []struct { 599 name string 600 ModelGroup []openrtb_ext.PriceFloorModelGroup 601 fn func(int) int 602 expectedModelGroup []openrtb_ext.PriceFloorModelGroup 603 }{ 604 { 605 name: "ModelGroup with default weight selection", 606 ModelGroup: []openrtb_ext.PriceFloorModelGroup{ 607 weightNilModelGroup, 608 }, 609 fn: func(i int) int { return 0 }, 610 expectedModelGroup: []openrtb_ext.PriceFloorModelGroup{ 611 weight01ModelGroup, 612 }, 613 }, 614 { 615 name: "ModelGroup with weight = 25 selection", 616 ModelGroup: []openrtb_ext.PriceFloorModelGroup{ 617 weight25ModelGroup, 618 weight50ModelGroup, 619 }, 620 fn: func(i int) int { return 5 }, 621 expectedModelGroup: []openrtb_ext.PriceFloorModelGroup{ 622 weight25ModelGroup, 623 }, 624 }, 625 { 626 name: "ModelGroup with weight = 50 selection", 627 ModelGroup: []openrtb_ext.PriceFloorModelGroup{ 628 weight50ModelGroup, 629 }, 630 fn: func(i int) int { return 55 }, 631 expectedModelGroup: []openrtb_ext.PriceFloorModelGroup{ 632 weight50ModelGroup, 633 }, 634 }, 635 { 636 name: "ModelGroup with weight = 25 selection", 637 ModelGroup: []openrtb_ext.PriceFloorModelGroup{ 638 weight25ModelGroup, 639 weight50ModelGroup, 640 }, 641 fn: func(i int) int { return 80 }, 642 expectedModelGroup: []openrtb_ext.PriceFloorModelGroup{ 643 weight25ModelGroup, 644 }, 645 }, 646 } 647 648 for _, tc := range testCases { 649 t.Run(tc.name, func(t *testing.T) { 650 resp := selectFloorModelGroup(tc.ModelGroup, tc.fn) 651 assert.Equal(t, resp, tc.expectedModelGroup) 652 }) 653 } 654 } 655 656 func TestGetMinFloorValue(t *testing.T) { 657 rates := map[string]map[string]float64{ 658 "USD": { 659 "INR": 81.17, 660 }, 661 } 662 663 type args struct { 664 floorExt *openrtb_ext.PriceFloorRules 665 imp openrtb2.Imp 666 conversions currency.Conversions 667 } 668 testCases := []struct { 669 name string 670 args args 671 want float64 672 want1 string 673 wantErr error 674 }{ 675 { 676 name: "Floor min is available in imp and floor ext", 677 args: args{ 678 floorExt: &openrtb_ext.PriceFloorRules{FloorMin: 2.0, FloorMinCur: "INR", Data: &openrtb_ext.PriceFloorData{Currency: "INR"}}, 679 imp: openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"floorMinCur": "INR","floorMin":1.0}}}`)}, 680 }, 681 want: 1, 682 want1: "INR", 683 }, 684 { 685 name: "Floor min and floor min currency is available in imp ext only", 686 args: args{ 687 floorExt: &openrtb_ext.PriceFloorRules{}, 688 imp: openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"floorMinCur": "INR", "floorMin": 1.0}}}`)}, 689 }, 690 want: 0.0123, 691 want1: "USD", 692 }, 693 { 694 name: "Floor min is available in floor ext only", 695 args: args{ 696 floorExt: &openrtb_ext.PriceFloorRules{FloorMin: 1.0, FloorMinCur: "EUR", Data: &openrtb_ext.PriceFloorData{Currency: "EUR"}}, 697 imp: openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{}}}`)}, 698 }, 699 want: 1.0, 700 want1: "EUR", 701 }, 702 { 703 name: "Floor min is available in floorExt and currency is available in imp", 704 args: args{ 705 floorExt: &openrtb_ext.PriceFloorRules{FloorMin: 2.0, Data: &openrtb_ext.PriceFloorData{Currency: "INR"}}, 706 imp: openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"floorMinCur": "INR"}}}`)}, 707 }, 708 want: 2, 709 want1: "INR", 710 }, 711 { 712 name: "Floor min is available in ImpExt and currency is available in floorExt", 713 args: args{ 714 floorExt: &openrtb_ext.PriceFloorRules{FloorMinCur: "USD", Data: &openrtb_ext.PriceFloorData{Currency: "INR"}}, 715 imp: openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"FloorMin": 2.0}}}`)}, 716 }, 717 want: 162.34, 718 want1: "INR", 719 }, 720 { 721 name: "Floor Min and floor Currency are in Imp and only floor currency is available in floor ext", 722 args: args{ 723 floorExt: &openrtb_ext.PriceFloorRules{FloorMinCur: "USD"}, 724 imp: openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"floorMinCur": "USD","floorMin":1.0}}}`)}, 725 }, 726 want: 1, 727 want1: "USD", 728 }, 729 { 730 name: "Currency are different in floor ext and imp", 731 args: args{ 732 floorExt: &openrtb_ext.PriceFloorRules{FloorMin: 0.0, FloorMinCur: "EUR", Data: &openrtb_ext.PriceFloorData{Currency: "INR"}}, 733 imp: openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"floorMinCur": "USD","floorMin":1.0}}}`)}, 734 }, 735 want: 81.17, 736 want1: "INR", 737 }, 738 { 739 name: "Floor min is 0 in imp ", 740 args: args{ 741 floorExt: &openrtb_ext.PriceFloorRules{FloorMin: 2.0, FloorMinCur: "JPY", Data: &openrtb_ext.PriceFloorData{Currency: "INR"}}, 742 imp: openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"floorMinCur": "USD","floorMin":0.0}}}`)}, 743 }, 744 want: 162.34, 745 want1: "INR", 746 }, 747 { 748 name: "Floor Currency is empty in imp", 749 args: args{ 750 floorExt: &openrtb_ext.PriceFloorRules{FloorMin: 1.0, FloorMinCur: "EUR", Data: &openrtb_ext.PriceFloorData{Currency: "EUR"}}, 751 imp: openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"floorMinCur": "","floorMin":-1.0}}}`)}, 752 }, 753 want: 1.0, 754 want1: "EUR", 755 }, 756 { 757 name: "Invalid input", 758 args: args{ 759 floorExt: &openrtb_ext.PriceFloorRules{FloorMinCur: "EUR", Data: &openrtb_ext.PriceFloorData{}}, 760 imp: openrtb2.Imp{Ext: json.RawMessage(`{`)}, 761 }, 762 want: 0.0, 763 want1: "", 764 wantErr: errors.New("Error in getting FloorMin value : 'expects \" or n, but found \x00'"), 765 }, 766 } 767 for _, tc := range testCases { 768 t.Run(tc.name, func(t *testing.T) { 769 got, got1, err := getMinFloorValue(tc.args.floorExt, &openrtb_ext.ImpWrapper{Imp: &tc.args.imp}, getCurrencyRates(rates)) 770 assert.Equal(t, tc.wantErr, err, tc.name) 771 assert.Equal(t, tc.want, got, tc.name) 772 assert.Equal(t, tc.want1, got1, tc.name) 773 }) 774 } 775 } 776 777 func TestSortCombinations(t *testing.T) { 778 type args struct { 779 comb [][]int 780 numSchemaFields int 781 } 782 tests := []struct { 783 name string 784 args args 785 expComb [][]int 786 }{ 787 { 788 name: "With schema fields = 3", 789 args: args{ 790 comb: [][]int{{0}, {1}, {2}}, 791 numSchemaFields: 3, 792 }, 793 expComb: [][]int{{2}, {1}, {0}}, 794 }, 795 { 796 name: "With schema fields = 3", 797 args: args{ 798 comb: [][]int{{0, 1}, {1, 2}, {0, 2}}, 799 numSchemaFields: 3, 800 }, 801 expComb: [][]int{{1, 2}, {0, 2}, {0, 1}}, 802 }, 803 { 804 name: "With schema fields = 4", 805 args: args{ 806 comb: [][]int{{0, 1, 2}, {1, 2, 3}, {0, 2, 3}, {0, 1, 3}}, 807 numSchemaFields: 3, 808 }, 809 expComb: [][]int{{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}}, 810 }, 811 } 812 for _, tt := range tests { 813 t.Run(tt.name, func(t *testing.T) { 814 sortCombinations(tt.args.comb, tt.args.numSchemaFields) 815 assert.Equal(t, tt.expComb, tt.args.comb) 816 }) 817 } 818 } 819 820 func TestGenerateCombinations(t *testing.T) { 821 822 tests := []struct { 823 name string 824 numSchemaFields int 825 numWildCard int 826 expComb [][]int 827 }{ 828 { 829 name: "With schema fields = 3, wildcard = 1", 830 numSchemaFields: 3, 831 numWildCard: 1, 832 expComb: [][]int{{0}, {1}, {2}}, 833 }, 834 { 835 name: "With schema fields = 3, wildcard = 2", 836 numSchemaFields: 3, 837 numWildCard: 2, 838 expComb: [][]int{{0, 1}, {0, 2}, {1, 2}}, 839 }, 840 { 841 name: "With schema fields = 3, wildcard = 3", 842 numSchemaFields: 3, 843 numWildCard: 3, 844 expComb: [][]int{{0, 1, 2}}, 845 }, 846 } 847 for _, tt := range tests { 848 t.Run(tt.name, func(t *testing.T) { 849 gotComb := generateCombinations(tt.numSchemaFields, tt.numWildCard) 850 assert.Equal(t, tt.expComb, gotComb) 851 }) 852 } 853 } 854 855 func TestGetDeviceType(t *testing.T) { 856 tests := []struct { 857 name string 858 request *openrtb2.BidRequest 859 want string 860 }{ 861 { 862 name: "user agent contains Phone", 863 request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (Phone Samsung Mobile; Win64; x64)"}}, 864 want: "phone", 865 }, 866 { 867 name: "user agent contains iPhone", 868 request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Safari(iPhone Apple Mobile)"}}, 869 want: "phone", 870 }, 871 { 872 name: "user agent contains Mobile.*Android", 873 request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (Mobile Android; Win64; x64)"}}, 874 want: "phone", 875 }, 876 { 877 name: "user agent contains Android.*Mobile", 878 request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (Android Redmi Mobile; Win64; x64)"}}, 879 want: "phone", 880 }, 881 { 882 name: "user agent contains Mobile.*Android", 883 request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (Mobile pixel Android; Win64; x64)"}}, 884 want: "phone", 885 }, 886 { 887 name: "user agent contains Windows NT touch", 888 request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (Windows NT touch 10.0; Win64; x64)"}}, 889 want: "tablet", 890 }, 891 { 892 name: "user agent contains ipad", 893 request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (ipad 13.10; Win64; x64)"}}, 894 want: "tablet", 895 }, 896 { 897 name: "user agent contains Window NT.*touch", 898 request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0; Touch)"}}, 899 want: "tablet", 900 }, 901 { 902 name: "user agent contains touch.* Window NT", 903 request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (touch realme Windows NT Win64; x64)"}}, 904 want: "tablet", 905 }, 906 { 907 name: "user agent contains Android", 908 request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (Android; Win64; x64)"}}, 909 want: "tablet", 910 }, 911 { 912 name: "user agent not matching phone or tablet", 913 request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}}, 914 want: "desktop", 915 }, 916 { 917 name: "empty user agent", 918 request: &openrtb2.BidRequest{Device: &openrtb2.Device{}}, 919 want: "*", 920 }, 921 } 922 for _, tt := range tests { 923 t.Run(tt.name, func(t *testing.T) { 924 got := getDeviceType(&openrtb_ext.RequestWrapper{BidRequest: tt.request}) 925 assert.Equal(t, tt.want, got) 926 }) 927 } 928 } 929 930 func TestGetAdUnitCode(t *testing.T) { 931 tests := []struct { 932 name string 933 imp *openrtb_ext.ImpWrapper 934 want string 935 }{ 936 { 937 name: "imp.ext.gpid", 938 imp: &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{Ext: json.RawMessage(`{"gpid":"test_gpid"}`)}}, 939 want: "test_gpid", 940 }, 941 { 942 name: "imp.TagID", 943 imp: &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{TagID: "tag_1"}}, 944 want: "tag_1", 945 }, 946 { 947 name: "imp.ext.data.pbadslot", 948 imp: &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{Ext: json.RawMessage(`{"data":{"pbadslot":"pbslot_1"}}`)}}, 949 want: "pbslot_1", 950 }, 951 { 952 name: "imp.ext.prebid.storedrequest.id", 953 imp: &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{Ext: json.RawMessage(`{"prebid": {"storedrequest":{"id":"123"}}}`)}}, 954 want: "123", 955 }, 956 { 957 name: "empty adUnitCode", 958 imp: &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{}}, 959 want: "*", 960 }, 961 } 962 963 for _, tt := range tests { 964 t.Run(tt.name, func(t *testing.T) { 965 got := getAdUnitCode(tt.imp) 966 assert.Equal(t, tt.want, got) 967 }) 968 } 969 } 970 971 func TestGetGptSlot(t *testing.T) { 972 tests := []struct { 973 name string 974 imp *openrtb_ext.ImpWrapper 975 want string 976 }{ 977 { 978 name: "imp.ext.data.adserver.adslot", 979 imp: &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{Ext: json.RawMessage(`{"data":{"adserver": {"name": "gam", "adslot": "slot_1"}}}`)}}, 980 want: "slot_1", 981 }, 982 { 983 name: "gptSlot = imp.ext.data.pbadslot", 984 imp: &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{Ext: json.RawMessage(`{"data":{"pbadslot":"pbslot_1"}}`)}}, 985 want: "pbslot_1", 986 }, 987 { 988 name: "empty gptSlot", 989 imp: &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{}}, 990 want: "*", 991 }, 992 } 993 for _, tt := range tests { 994 t.Run(tt.name, func(t *testing.T) { 995 got := getGptSlot(tt.imp) 996 assert.Equal(t, tt.want, got) 997 }) 998 } 999 } 1000 1001 func TestGetSizeValue(t *testing.T) { 1002 tests := []struct { 1003 name string 1004 imp *openrtb2.Imp 1005 want string 1006 }{ 1007 { 1008 name: "banner: only one size exists in imp.banner.format", 1009 imp: &openrtb2.Imp{Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}}, 1010 want: "300x250", 1011 }, 1012 { 1013 name: "banner: no imp.banner.format", 1014 imp: &openrtb2.Imp{Banner: &openrtb2.Banner{W: getInt64Ptr(320), H: getInt64Ptr(240)}}, 1015 want: "320x240", 1016 }, 1017 { 1018 name: "video: imp.video.w and imp.video.h present", 1019 imp: &openrtb2.Imp{Video: &openrtb2.Video{W: ptrutil.ToPtr[int64](120), H: ptrutil.ToPtr[int64](240)}}, 1020 want: "120x240", 1021 }, 1022 { 1023 name: "banner: more than one size exists in imp.banner.format", 1024 imp: &openrtb2.Imp{Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}, {W: 200, H: 300}}}}, 1025 want: "*", 1026 }, 1027 { 1028 name: "Audo creative", 1029 imp: &openrtb2.Imp{Audio: &openrtb2.Audio{}}, 1030 want: "*", 1031 }, 1032 } 1033 for _, tt := range tests { 1034 t.Run(tt.name, func(t *testing.T) { 1035 got := getSizeValue(tt.imp) 1036 assert.Equal(t, tt.want, got) 1037 }) 1038 } 1039 } 1040 1041 func TestGetMediaType(t *testing.T) { 1042 tests := []struct { 1043 name string 1044 imp *openrtb2.Imp 1045 want string 1046 }{ 1047 { 1048 name: "more than one of these: imp.banner, imp.video, imp.native, imp.audio present", 1049 imp: &openrtb2.Imp{Video: &openrtb2.Video{W: ptrutil.ToPtr[int64](120), H: ptrutil.ToPtr[int64](240)}, Banner: &openrtb2.Banner{W: getInt64Ptr(320), H: getInt64Ptr(240)}}, 1050 want: "*", 1051 }, 1052 { 1053 name: "only banner present", 1054 imp: &openrtb2.Imp{Banner: &openrtb2.Banner{W: getInt64Ptr(320), H: getInt64Ptr(240)}}, 1055 want: "banner", 1056 }, 1057 { 1058 name: "video-outstream present", 1059 imp: &openrtb2.Imp{Video: &openrtb2.Video{W: ptrutil.ToPtr[int64](120), H: ptrutil.ToPtr[int64](240), Placement: 2}}, 1060 want: "video-outstream", 1061 }, 1062 { 1063 name: "video-instream present", 1064 imp: &openrtb2.Imp{Video: &openrtb2.Video{W: ptrutil.ToPtr[int64](120), H: ptrutil.ToPtr[int64](240), Placement: 1}}, 1065 want: "video", 1066 }, 1067 { 1068 name: "only audio", 1069 imp: &openrtb2.Imp{Audio: &openrtb2.Audio{MinDuration: 10}}, 1070 want: "audio", 1071 }, 1072 { 1073 name: "only native", 1074 imp: &openrtb2.Imp{Native: &openrtb2.Native{Request: "test_req"}}, 1075 want: "native", 1076 }, 1077 } 1078 1079 for _, tt := range tests { 1080 t.Run(tt.name, func(t *testing.T) { 1081 got := getMediaType(tt.imp) 1082 assert.Equal(t, tt.want, got) 1083 }) 1084 } 1085 } 1086 1087 func TestGetSiteDomain(t *testing.T) { 1088 type args struct { 1089 request *openrtb_ext.RequestWrapper 1090 } 1091 tests := []struct { 1092 name string 1093 request *openrtb_ext.RequestWrapper 1094 want string 1095 }{ 1096 { 1097 name: "Site Domain present", 1098 request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Site: &openrtb2.Site{Domain: "abc.xyz.com"}}}, 1099 want: "abc.xyz.com", 1100 }, 1101 { 1102 name: "Site Domain not present", 1103 request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Site: &openrtb2.Site{}}}, 1104 want: "*", 1105 }, 1106 { 1107 name: "App Domain present", 1108 request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{Domain: "cde.rtu.com"}}}, 1109 want: "cde.rtu.com", 1110 }, 1111 { 1112 name: "App Domain not present", 1113 request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{}}}, 1114 want: "*", 1115 }, 1116 } 1117 for _, tt := range tests { 1118 t.Run(tt.name, func(t *testing.T) { 1119 got := getSiteDomain(tt.request) 1120 assert.Equal(t, tt.want, got) 1121 }) 1122 } 1123 } 1124 1125 func TestGetPublisherDomain(t *testing.T) { 1126 type args struct { 1127 } 1128 tests := []struct { 1129 name string 1130 request *openrtb_ext.RequestWrapper 1131 want string 1132 }{ 1133 { 1134 name: "Site publisher domain present", 1135 request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Site: &openrtb2.Site{Publisher: &openrtb2.Publisher{Domain: "qwe.xyz.com"}}}}, 1136 want: "qwe.xyz.com", 1137 }, 1138 { 1139 name: "Site publisher domain not present", 1140 request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Site: &openrtb2.Site{Publisher: &openrtb2.Publisher{}}}}, 1141 want: "*", 1142 }, 1143 { 1144 name: "App publisher domain present", 1145 request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{Publisher: &openrtb2.Publisher{Domain: "xyz.com"}}}}, 1146 want: "xyz.com", 1147 }, 1148 { 1149 name: "App publisher domain not present", 1150 request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{}}}, 1151 want: "*", 1152 }, 1153 } 1154 for _, tt := range tests { 1155 t.Run(tt.name, func(t *testing.T) { 1156 got := getPublisherDomain(tt.request) 1157 assert.Equal(t, tt.want, got) 1158 }) 1159 } 1160 } 1161 1162 func TestGetDomain(t *testing.T) { 1163 type args struct { 1164 } 1165 tests := []struct { 1166 name string 1167 request *openrtb_ext.RequestWrapper 1168 want string 1169 }{ 1170 { 1171 name: "Site domain present", 1172 request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Site: &openrtb2.Site{Domain: "qwe.xyz.com", Publisher: &openrtb2.Publisher{Domain: "abc.xyz.com"}}}}, 1173 want: "qwe.xyz.com", 1174 }, 1175 { 1176 name: "Site publisher domain present", 1177 request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Site: &openrtb2.Site{Publisher: &openrtb2.Publisher{Domain: "abc.xyz.com"}}}}, 1178 want: "abc.xyz.com", 1179 }, 1180 { 1181 name: "Site domain not present", 1182 request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Site: &openrtb2.Site{Publisher: &openrtb2.Publisher{}}}}, 1183 want: "*", 1184 }, 1185 { 1186 name: "App publisher domain present", 1187 request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{Domain: "abc.com", Publisher: &openrtb2.Publisher{Domain: "xyz.com"}}}}, 1188 want: "abc.com", 1189 }, 1190 { 1191 name: "App domain present", 1192 request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{Publisher: &openrtb2.Publisher{Domain: "xyz.com"}}}}, 1193 want: "xyz.com", 1194 }, 1195 { 1196 name: "App domain not present", 1197 request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{}}}, 1198 want: "*", 1199 }, 1200 } 1201 for _, tt := range tests { 1202 t.Run(tt.name, func(t *testing.T) { 1203 got := getDomain(tt.request) 1204 assert.Equal(t, tt.want, got) 1205 }) 1206 } 1207 } 1208 1209 func getIntPtr(v int) *int { 1210 return &v 1211 } 1212 1213 func getInt64Ptr(v int64) *int64 { 1214 return &v 1215 }