github.com/prebid/prebid-server/v2@v2.18.0/config/account_test.go (about) 1 package config 2 3 import ( 4 "encoding/json" 5 "errors" 6 "testing" 7 8 "github.com/prebid/go-gdpr/consentconstants" 9 "github.com/prebid/prebid-server/v2/openrtb_ext" 10 "github.com/stretchr/testify/assert" 11 ) 12 13 func TestAccountGDPREnabledForChannelType(t *testing.T) { 14 trueValue, falseValue := true, false 15 16 tests := []struct { 17 description string 18 giveChannelType ChannelType 19 giveGDPREnabled *bool 20 giveWebGDPREnabled *bool 21 wantEnabled *bool 22 }{ 23 { 24 description: "GDPR Web channel enabled, general GDPR disabled", 25 giveChannelType: ChannelWeb, 26 giveGDPREnabled: &falseValue, 27 giveWebGDPREnabled: &trueValue, 28 wantEnabled: &trueValue, 29 }, 30 { 31 description: "GDPR Web channel disabled, general GDPR enabled", 32 giveChannelType: ChannelWeb, 33 giveGDPREnabled: &trueValue, 34 giveWebGDPREnabled: &falseValue, 35 wantEnabled: &falseValue, 36 }, 37 { 38 description: "GDPR Web channel unspecified, general GDPR disabled", 39 giveChannelType: ChannelWeb, 40 giveGDPREnabled: &falseValue, 41 giveWebGDPREnabled: nil, 42 wantEnabled: &falseValue, 43 }, 44 { 45 description: "GDPR Web channel unspecified, general GDPR enabled", 46 giveChannelType: ChannelWeb, 47 giveGDPREnabled: &trueValue, 48 giveWebGDPREnabled: nil, 49 wantEnabled: &trueValue, 50 }, 51 { 52 description: "GDPR Web channel unspecified, general GDPR unspecified", 53 giveChannelType: ChannelWeb, 54 giveGDPREnabled: nil, 55 giveWebGDPREnabled: nil, 56 wantEnabled: nil, 57 }, 58 } 59 60 for _, tt := range tests { 61 account := Account{ 62 GDPR: AccountGDPR{ 63 Enabled: tt.giveGDPREnabled, 64 ChannelEnabled: AccountChannel{ 65 Web: tt.giveWebGDPREnabled, 66 }, 67 }, 68 } 69 70 enabled := account.GDPR.EnabledForChannelType(tt.giveChannelType) 71 72 if tt.wantEnabled == nil { 73 assert.Nil(t, enabled, tt.description) 74 } else { 75 assert.NotNil(t, enabled, tt.description) 76 assert.Equal(t, *tt.wantEnabled, *enabled, tt.description) 77 } 78 } 79 } 80 81 func TestAccountCCPAEnabledForChannelType(t *testing.T) { 82 trueValue, falseValue := true, false 83 84 tests := []struct { 85 description string 86 giveChannelType ChannelType 87 giveCCPAEnabled *bool 88 giveWebCCPAEnabled *bool 89 wantEnabled *bool 90 }{ 91 { 92 description: "CCPA Web channel enabled, general CCPA disabled", 93 giveChannelType: ChannelWeb, 94 giveCCPAEnabled: &falseValue, 95 giveWebCCPAEnabled: &trueValue, 96 wantEnabled: &trueValue, 97 }, 98 { 99 description: "CCPA Web channel disabled, general CCPA enabled", 100 giveChannelType: ChannelWeb, 101 giveCCPAEnabled: &trueValue, 102 giveWebCCPAEnabled: &falseValue, 103 wantEnabled: &falseValue, 104 }, 105 { 106 description: "CCPA Web channel unspecified, general CCPA disabled", 107 giveChannelType: ChannelWeb, 108 giveCCPAEnabled: &falseValue, 109 giveWebCCPAEnabled: nil, 110 wantEnabled: &falseValue, 111 }, 112 { 113 description: "CCPA Web channel unspecified, general CCPA enabled", 114 giveChannelType: ChannelWeb, 115 giveCCPAEnabled: &trueValue, 116 giveWebCCPAEnabled: nil, 117 wantEnabled: &trueValue, 118 }, 119 { 120 description: "CCPA Web channel unspecified, general CCPA unspecified", 121 giveChannelType: ChannelWeb, 122 giveCCPAEnabled: nil, 123 giveWebCCPAEnabled: nil, 124 wantEnabled: nil, 125 }, 126 } 127 128 for _, tt := range tests { 129 account := Account{ 130 CCPA: AccountCCPA{ 131 Enabled: tt.giveCCPAEnabled, 132 ChannelEnabled: AccountChannel{ 133 Web: tt.giveWebCCPAEnabled, 134 }, 135 }, 136 } 137 138 enabled := account.CCPA.EnabledForChannelType(tt.giveChannelType) 139 140 if tt.wantEnabled == nil { 141 assert.Nil(t, enabled, tt.description) 142 } else { 143 assert.NotNil(t, enabled, tt.description) 144 assert.Equal(t, *tt.wantEnabled, *enabled, tt.description) 145 } 146 } 147 } 148 149 func TestAccountChannelGetByChannelType(t *testing.T) { 150 trueValue, falseValue := true, false 151 152 tests := []struct { 153 description string 154 giveAMPEnabled *bool 155 giveAppEnabled *bool 156 giveVideoEnabled *bool 157 giveWebEnabled *bool 158 giveDOOHEnabled *bool 159 giveChannelType ChannelType 160 wantEnabled *bool 161 }{ 162 { 163 description: "AMP channel setting unspecified, returns nil", 164 giveChannelType: ChannelAMP, 165 wantEnabled: nil, 166 }, 167 { 168 description: "AMP channel disabled, returns false", 169 giveAMPEnabled: &falseValue, 170 giveChannelType: ChannelAMP, 171 wantEnabled: &falseValue, 172 }, 173 { 174 description: "AMP channel enabled, returns true", 175 giveAMPEnabled: &trueValue, 176 giveChannelType: ChannelAMP, 177 wantEnabled: &trueValue, 178 }, 179 { 180 description: "App channel setting unspecified, returns nil", 181 giveChannelType: ChannelApp, 182 wantEnabled: nil, 183 }, 184 { 185 description: "App channel disabled, returns false", 186 giveAppEnabled: &falseValue, 187 giveChannelType: ChannelApp, 188 wantEnabled: &falseValue, 189 }, 190 { 191 description: "App channel enabled, returns true", 192 giveAppEnabled: &trueValue, 193 giveChannelType: ChannelApp, 194 wantEnabled: &trueValue, 195 }, 196 { 197 description: "Video channel setting unspecified, returns nil", 198 giveChannelType: ChannelVideo, 199 wantEnabled: nil, 200 }, 201 { 202 description: "Video channel disabled, returns false", 203 giveVideoEnabled: &falseValue, 204 giveChannelType: ChannelVideo, 205 wantEnabled: &falseValue, 206 }, 207 { 208 description: "Video channel enabled, returns true", 209 giveVideoEnabled: &trueValue, 210 giveChannelType: ChannelVideo, 211 wantEnabled: &trueValue, 212 }, 213 { 214 description: "Web channel setting unspecified, returns nil", 215 giveChannelType: ChannelWeb, 216 wantEnabled: nil, 217 }, 218 { 219 description: "Web channel disabled, returns false", 220 giveWebEnabled: &falseValue, 221 giveChannelType: ChannelWeb, 222 wantEnabled: &falseValue, 223 }, 224 { 225 description: "Web channel enabled, returns true", 226 giveWebEnabled: &trueValue, 227 giveChannelType: ChannelWeb, 228 wantEnabled: &trueValue, 229 }, 230 { 231 description: "DOOH channel setting unspecified, returns nil", 232 giveChannelType: ChannelDOOH, 233 wantEnabled: nil, 234 }, 235 { 236 description: "DOOH channel disabled, returns false", 237 giveDOOHEnabled: &falseValue, 238 giveChannelType: ChannelDOOH, 239 wantEnabled: &falseValue, 240 }, 241 { 242 description: "DOOH channel enabled, returns true", 243 giveDOOHEnabled: &trueValue, 244 giveChannelType: ChannelDOOH, 245 wantEnabled: &trueValue, 246 }, 247 } 248 249 for _, tt := range tests { 250 accountChannel := AccountChannel{ 251 AMP: tt.giveAMPEnabled, 252 App: tt.giveAppEnabled, 253 Video: tt.giveVideoEnabled, 254 Web: tt.giveWebEnabled, 255 DOOH: tt.giveDOOHEnabled, 256 } 257 258 result := accountChannel.GetByChannelType(tt.giveChannelType) 259 if tt.wantEnabled == nil { 260 assert.Nil(t, result, tt.description) 261 } else { 262 assert.NotNil(t, result, tt.description) 263 assert.Equal(t, *tt.wantEnabled, *result, tt.description) 264 } 265 } 266 } 267 268 func TestPurposeEnforced(t *testing.T) { 269 True := true 270 False := false 271 272 tests := []struct { 273 description string 274 givePurposeConfigNil bool 275 givePurpose1Enforced *bool 276 givePurpose2Enforced *bool 277 givePurpose consentconstants.Purpose 278 wantEnforced bool 279 wantEnforcedSet bool 280 }{ 281 { 282 description: "Purpose config is nil", 283 givePurposeConfigNil: true, 284 givePurpose: 1, 285 wantEnforced: true, 286 wantEnforcedSet: false, 287 }, 288 { 289 description: "Purpose 1 Enforced not set", 290 givePurpose1Enforced: nil, 291 givePurpose: 1, 292 wantEnforced: true, 293 wantEnforcedSet: false, 294 }, 295 { 296 description: "Purpose 1 Enforced set to full enforcement", 297 givePurpose1Enforced: &True, 298 givePurpose: 1, 299 wantEnforced: true, 300 wantEnforcedSet: true, 301 }, 302 { 303 description: "Purpose 1 Enforced set to no enforcement", 304 givePurpose1Enforced: &False, 305 givePurpose: 1, 306 wantEnforced: false, 307 wantEnforcedSet: true, 308 }, 309 { 310 description: "Purpose 2 Enforced set to full enforcement", 311 givePurpose2Enforced: &True, 312 givePurpose: 2, 313 wantEnforced: true, 314 wantEnforcedSet: true, 315 }, 316 } 317 318 for _, tt := range tests { 319 accountGDPR := AccountGDPR{} 320 321 if !tt.givePurposeConfigNil { 322 accountGDPR.PurposeConfigs = map[consentconstants.Purpose]*AccountGDPRPurpose{ 323 1: { 324 EnforcePurpose: tt.givePurpose1Enforced, 325 }, 326 2: { 327 EnforcePurpose: tt.givePurpose2Enforced, 328 }, 329 } 330 } 331 332 value, present := accountGDPR.PurposeEnforced(tt.givePurpose) 333 334 assert.Equal(t, tt.wantEnforced, value, tt.description) 335 assert.Equal(t, tt.wantEnforcedSet, present, tt.description) 336 } 337 } 338 339 func TestPurposeEnforcementAlgo(t *testing.T) { 340 tests := []struct { 341 description string 342 givePurposeConfigNil bool 343 givePurpose1Algo TCF2EnforcementAlgo 344 givePurpose2Algo TCF2EnforcementAlgo 345 givePurpose consentconstants.Purpose 346 wantAlgo TCF2EnforcementAlgo 347 wantAlgoSet bool 348 }{ 349 { 350 description: "Purpose config is nil", 351 givePurposeConfigNil: true, 352 givePurpose: 1, 353 wantAlgo: TCF2UndefinedEnforcement, 354 wantAlgoSet: false, 355 }, 356 { 357 description: "Purpose 1 enforcement algo is undefined", 358 givePurpose1Algo: TCF2UndefinedEnforcement, 359 givePurpose: 1, 360 wantAlgo: TCF2UndefinedEnforcement, 361 wantAlgoSet: false, 362 }, 363 { 364 description: "Purpose 1 enforcement algo set to basic", 365 givePurpose1Algo: TCF2BasicEnforcement, 366 givePurpose: 1, 367 wantAlgo: TCF2BasicEnforcement, 368 wantAlgoSet: true, 369 }, 370 { 371 description: "Purpose 1 enforcement algo set to full", 372 givePurpose1Algo: TCF2FullEnforcement, 373 givePurpose: 1, 374 wantAlgo: TCF2FullEnforcement, 375 wantAlgoSet: true, 376 }, 377 { 378 description: "Purpose 2 Enforcement algo set to basic", 379 givePurpose2Algo: TCF2BasicEnforcement, 380 givePurpose: 2, 381 wantAlgo: TCF2BasicEnforcement, 382 wantAlgoSet: true, 383 }, 384 } 385 386 for _, tt := range tests { 387 accountGDPR := AccountGDPR{} 388 389 if !tt.givePurposeConfigNil { 390 accountGDPR.PurposeConfigs = map[consentconstants.Purpose]*AccountGDPRPurpose{ 391 1: { 392 EnforceAlgoID: tt.givePurpose1Algo, 393 }, 394 2: { 395 EnforceAlgoID: tt.givePurpose2Algo, 396 }, 397 } 398 } 399 400 value, present := accountGDPR.PurposeEnforcementAlgo(tt.givePurpose) 401 402 assert.Equal(t, tt.wantAlgo, value, tt.description) 403 assert.Equal(t, tt.wantAlgoSet, present, tt.description) 404 } 405 } 406 407 func TestPurposeEnforcingVendors(t *testing.T) { 408 tests := []struct { 409 description string 410 givePurposeConfigNil bool 411 givePurpose1Enforcing *bool 412 givePurpose2Enforcing *bool 413 givePurpose consentconstants.Purpose 414 wantEnforcing bool 415 wantEnforcingSet bool 416 }{ 417 { 418 description: "Purpose config is nil", 419 givePurposeConfigNil: true, 420 givePurpose: 1, 421 wantEnforcing: true, 422 wantEnforcingSet: false, 423 }, 424 { 425 description: "Purpose 1 Enforcing not set", 426 givePurpose1Enforcing: nil, 427 givePurpose: 1, 428 wantEnforcing: true, 429 wantEnforcingSet: false, 430 }, 431 { 432 description: "Purpose 1 Enforcing set to true", 433 givePurpose1Enforcing: &[]bool{true}[0], 434 givePurpose: 1, 435 wantEnforcing: true, 436 wantEnforcingSet: true, 437 }, 438 { 439 description: "Purpose 1 Enforcing set to false", 440 givePurpose1Enforcing: &[]bool{false}[0], 441 givePurpose: 1, 442 wantEnforcing: false, 443 wantEnforcingSet: true, 444 }, 445 { 446 description: "Purpose 2 Enforcing set to true", 447 givePurpose2Enforcing: &[]bool{true}[0], 448 givePurpose: 2, 449 wantEnforcing: true, 450 wantEnforcingSet: true, 451 }, 452 } 453 454 for _, tt := range tests { 455 accountGDPR := AccountGDPR{} 456 457 if !tt.givePurposeConfigNil { 458 accountGDPR.PurposeConfigs = map[consentconstants.Purpose]*AccountGDPRPurpose{ 459 1: { 460 EnforceVendors: tt.givePurpose1Enforcing, 461 }, 462 2: { 463 EnforceVendors: tt.givePurpose2Enforcing, 464 }, 465 } 466 } 467 468 value, present := accountGDPR.PurposeEnforcingVendors(tt.givePurpose) 469 470 assert.Equal(t, tt.wantEnforcing, value, tt.description) 471 assert.Equal(t, tt.wantEnforcingSet, present, tt.description) 472 } 473 } 474 475 func TestPurposeVendorExceptions(t *testing.T) { 476 tests := []struct { 477 description string 478 givePurposeConfigNil bool 479 givePurpose1ExceptionMap map[string]struct{} 480 givePurpose2ExceptionMap map[string]struct{} 481 givePurpose consentconstants.Purpose 482 wantExceptionMap map[string]struct{} 483 }{ 484 { 485 description: "Purpose config is nil", 486 givePurposeConfigNil: true, 487 givePurpose: 1, 488 wantExceptionMap: nil, 489 }, 490 { 491 description: "Nil - exception map not defined for purpose", 492 givePurpose: 1, 493 wantExceptionMap: nil, 494 }, 495 { 496 description: "Empty - exception map empty for purpose", 497 givePurpose: 1, 498 givePurpose1ExceptionMap: map[string]struct{}{}, 499 wantExceptionMap: map[string]struct{}{}, 500 }, 501 { 502 description: "Nonempty - exception map with multiple entries for purpose", 503 givePurpose: 1, 504 givePurpose1ExceptionMap: map[string]struct{}{"rubicon": {}, "appnexus": {}, "index": {}}, 505 wantExceptionMap: map[string]struct{}{"rubicon": {}, "appnexus": {}, "index": {}}, 506 }, 507 { 508 description: "Nonempty - exception map with multiple entries for different purpose", 509 givePurpose: 2, 510 givePurpose1ExceptionMap: map[string]struct{}{"rubicon": {}, "appnexus": {}, "index": {}}, 511 givePurpose2ExceptionMap: map[string]struct{}{"rubicon": {}, "appnexus": {}, "openx": {}}, 512 wantExceptionMap: map[string]struct{}{"rubicon": {}, "appnexus": {}, "openx": {}}, 513 }, 514 } 515 516 for _, tt := range tests { 517 accountGDPR := AccountGDPR{} 518 519 if !tt.givePurposeConfigNil { 520 accountGDPR.PurposeConfigs = map[consentconstants.Purpose]*AccountGDPRPurpose{ 521 1: { 522 VendorExceptionMap: tt.givePurpose1ExceptionMap, 523 }, 524 2: { 525 VendorExceptionMap: tt.givePurpose2ExceptionMap, 526 }, 527 } 528 } 529 530 value, present := accountGDPR.PurposeVendorExceptions(tt.givePurpose) 531 532 assert.Equal(t, tt.wantExceptionMap, value, tt.description) 533 if tt.wantExceptionMap == nil { 534 assert.Equal(t, false, present) 535 } else { 536 assert.Equal(t, true, present) 537 } 538 } 539 } 540 541 func TestFeatureOneEnforced(t *testing.T) { 542 tests := []struct { 543 description string 544 giveEnforce *bool 545 wantEnforcedSet bool 546 wantEnforced bool 547 }{ 548 { 549 description: "Special feature 1 enforce not set", 550 giveEnforce: nil, 551 wantEnforcedSet: false, 552 wantEnforced: true, 553 }, 554 { 555 description: "Special feature 1 enforce set to true", 556 giveEnforce: &[]bool{true}[0], 557 wantEnforcedSet: true, 558 wantEnforced: true, 559 }, 560 { 561 description: "Special feature 1 enforce set to false", 562 giveEnforce: &[]bool{false}[0], 563 wantEnforcedSet: true, 564 wantEnforced: false, 565 }, 566 } 567 568 for _, tt := range tests { 569 accountGDPR := AccountGDPR{ 570 SpecialFeature1: AccountGDPRSpecialFeature{ 571 Enforce: tt.giveEnforce, 572 }, 573 } 574 575 value, present := accountGDPR.FeatureOneEnforced() 576 577 assert.Equal(t, tt.wantEnforced, value, tt.description) 578 assert.Equal(t, tt.wantEnforcedSet, present, tt.description) 579 } 580 } 581 582 func TestFeatureOneVendorException(t *testing.T) { 583 tests := []struct { 584 description string 585 giveExceptionMap map[openrtb_ext.BidderName]struct{} 586 giveBidder openrtb_ext.BidderName 587 wantVendorExceptionSet bool 588 wantIsVendorException bool 589 }{ 590 { 591 description: "Nil - exception map not defined", 592 giveBidder: "appnexus", 593 wantVendorExceptionSet: false, 594 wantIsVendorException: false, 595 }, 596 { 597 description: "Empty - exception map empty", 598 giveExceptionMap: map[openrtb_ext.BidderName]struct{}{}, 599 giveBidder: "appnexus", 600 wantVendorExceptionSet: true, 601 wantIsVendorException: false, 602 }, 603 { 604 description: "One - bidder found in exception map containing one entry", 605 giveExceptionMap: map[openrtb_ext.BidderName]struct{}{"appnexus": {}}, 606 giveBidder: "appnexus", 607 wantVendorExceptionSet: true, 608 wantIsVendorException: true, 609 }, 610 { 611 description: "Many - bidder found in exception map containing multiple entries", 612 giveExceptionMap: map[openrtb_ext.BidderName]struct{}{"rubicon": {}, "appnexus": {}, "index": {}}, 613 giveBidder: "appnexus", 614 wantVendorExceptionSet: true, 615 wantIsVendorException: true, 616 }, 617 { 618 description: "Many - bidder not found in exception map containing multiple entries", 619 giveExceptionMap: map[openrtb_ext.BidderName]struct{}{"rubicon": {}, "appnexus": {}, "index": {}}, 620 giveBidder: "openx", 621 wantVendorExceptionSet: true, 622 wantIsVendorException: false, 623 }, 624 } 625 626 for _, tt := range tests { 627 accountGDPR := AccountGDPR{ 628 SpecialFeature1: AccountGDPRSpecialFeature{ 629 VendorExceptionMap: tt.giveExceptionMap, 630 }, 631 } 632 633 value, present := accountGDPR.FeatureOneVendorException(tt.giveBidder) 634 635 assert.Equal(t, tt.wantIsVendorException, value, tt.description) 636 assert.Equal(t, tt.wantVendorExceptionSet, present, tt.description) 637 } 638 } 639 640 func TestPurposeOneTreatmentEnabled(t *testing.T) { 641 tests := []struct { 642 description string 643 giveEnabled *bool 644 wantEnabledSet bool 645 wantEnabled bool 646 }{ 647 { 648 description: "Purpose one treatment enabled not set", 649 giveEnabled: nil, 650 wantEnabledSet: false, 651 wantEnabled: true, 652 }, 653 { 654 description: "Purpose one treatment enabled set to true", 655 giveEnabled: &[]bool{true}[0], 656 wantEnabledSet: true, 657 wantEnabled: true, 658 }, 659 { 660 description: "Purpose one treatment enabled set to false", 661 giveEnabled: &[]bool{false}[0], 662 wantEnabledSet: true, 663 wantEnabled: false, 664 }, 665 } 666 667 for _, tt := range tests { 668 accountGDPR := AccountGDPR{ 669 PurposeOneTreatment: AccountGDPRPurposeOneTreatment{ 670 Enabled: tt.giveEnabled, 671 }, 672 } 673 674 value, present := accountGDPR.PurposeOneTreatmentEnabled() 675 676 assert.Equal(t, tt.wantEnabled, value, tt.description) 677 assert.Equal(t, tt.wantEnabledSet, present, tt.description) 678 } 679 } 680 681 func TestPurposeOneTreatmentAccessAllowed(t *testing.T) { 682 tests := []struct { 683 description string 684 giveAllowed *bool 685 wantAllowedSet bool 686 wantAllowed bool 687 }{ 688 { 689 description: "Purpose one treatment access allowed not set", 690 giveAllowed: nil, 691 wantAllowedSet: false, 692 wantAllowed: true, 693 }, 694 { 695 description: "Purpose one treatment access allowed set to true", 696 giveAllowed: &[]bool{true}[0], 697 wantAllowedSet: true, 698 wantAllowed: true, 699 }, 700 { 701 description: "Purpose one treatment access allowed set to false", 702 giveAllowed: &[]bool{false}[0], 703 wantAllowedSet: true, 704 wantAllowed: false, 705 }, 706 } 707 708 for _, tt := range tests { 709 accountGDPR := AccountGDPR{ 710 PurposeOneTreatment: AccountGDPRPurposeOneTreatment{ 711 AccessAllowed: tt.giveAllowed, 712 }, 713 } 714 715 value, present := accountGDPR.PurposeOneTreatmentAccessAllowed() 716 717 assert.Equal(t, tt.wantAllowed, value, tt.description) 718 assert.Equal(t, tt.wantAllowedSet, present, tt.description) 719 } 720 } 721 722 func TestModulesGetConfig(t *testing.T) { 723 modules := AccountModules{ 724 "acme": { 725 "foo": json.RawMessage(`{"foo": "bar"}`), 726 "foo.bar": json.RawMessage(`{"foo": "bar"}`), 727 }, 728 "acme.foo": { 729 "baz": json.RawMessage(`{"foo": "bar"}`), 730 }, 731 } 732 733 testCases := []struct { 734 description string 735 givenId string 736 givenModules AccountModules 737 expectedConfig json.RawMessage 738 expectedError error 739 }{ 740 { 741 description: "Returns module config if found by ID", 742 givenId: "acme.foo", 743 givenModules: modules, 744 expectedConfig: json.RawMessage(`{"foo": "bar"}`), 745 expectedError: nil, 746 }, 747 { 748 description: "Returns module config if found by ID", 749 givenId: "acme.foo.bar", 750 givenModules: modules, 751 expectedConfig: json.RawMessage(`{"foo": "bar"}`), 752 expectedError: nil, 753 }, 754 { 755 description: "Returns nil config if wrong ID provided", 756 givenId: "invalid_id", 757 givenModules: modules, 758 expectedConfig: nil, 759 expectedError: errors.New("ID must consist of vendor and module names separated by dot, got: invalid_id"), 760 }, 761 { 762 description: "Returns nil config if no matching module exists", 763 givenId: "acme.bar", 764 givenModules: modules, 765 expectedConfig: nil, 766 expectedError: nil, 767 }, 768 { 769 description: "Returns nil config if no matching module exists", 770 givenId: "acme.foo.baz", 771 givenModules: modules, 772 expectedConfig: nil, 773 expectedError: nil, 774 }, 775 { 776 description: "Returns nil config if no module configs defined in account", 777 givenId: "acme.foo", 778 givenModules: nil, 779 expectedConfig: nil, 780 expectedError: nil, 781 }, 782 } 783 784 for _, test := range testCases { 785 t.Run(test.description, func(t *testing.T) { 786 gotConfig, err := test.givenModules.ModuleConfig(test.givenId) 787 assert.Equal(t, test.expectedError, err) 788 assert.Equal(t, test.expectedConfig, gotConfig) 789 }) 790 } 791 } 792 793 func TestAccountPriceFloorsValidate(t *testing.T) { 794 tests := []struct { 795 description string 796 pf *AccountPriceFloors 797 want []error 798 }{ 799 { 800 description: "valid configuration", 801 pf: &AccountPriceFloors{ 802 EnforceFloorsRate: 100, 803 MaxRule: 200, 804 MaxSchemaDims: 10, 805 Fetcher: AccountFloorFetch{ 806 Period: 300, 807 MaxAge: 600, 808 Timeout: 12, 809 }, 810 }, 811 }, 812 { 813 description: "Invalid configuration: EnforceFloorRate:110", 814 pf: &AccountPriceFloors{ 815 EnforceFloorsRate: 110, 816 Fetcher: AccountFloorFetch{ 817 Period: 300, 818 MaxAge: 600, 819 Timeout: 12, 820 }, 821 }, 822 want: []error{errors.New("account_defaults.price_floors.enforce_floors_rate should be between 0 and 100")}, 823 }, 824 { 825 description: "Invalid configuration: EnforceFloorRate:-10", 826 pf: &AccountPriceFloors{ 827 EnforceFloorsRate: -10, 828 Fetcher: AccountFloorFetch{ 829 Period: 300, 830 MaxAge: 600, 831 Timeout: 12, 832 }, 833 }, 834 want: []error{errors.New("account_defaults.price_floors.enforce_floors_rate should be between 0 and 100")}, 835 }, 836 { 837 description: "Invalid configuration: MaxRule:-20", 838 pf: &AccountPriceFloors{ 839 MaxRule: -20, 840 Fetcher: AccountFloorFetch{ 841 Period: 300, 842 MaxAge: 600, 843 Timeout: 12, 844 }, 845 }, 846 want: []error{errors.New("account_defaults.price_floors.max_rules should be between 0 and 2147483647")}, 847 }, 848 { 849 description: "Invalid configuration: MaxSchemaDims:100", 850 pf: &AccountPriceFloors{ 851 MaxSchemaDims: 100, 852 Fetcher: AccountFloorFetch{ 853 Period: 300, 854 MaxAge: 600, 855 Timeout: 12, 856 }, 857 }, 858 want: []error{errors.New("account_defaults.price_floors.max_schema_dims should be between 0 and 20")}, 859 }, 860 { 861 description: "Invalid period for fetch", 862 pf: &AccountPriceFloors{ 863 EnforceFloorsRate: 100, 864 MaxRule: 200, 865 MaxSchemaDims: 10, 866 Fetcher: AccountFloorFetch{ 867 Period: 100, 868 MaxAge: 600, 869 Timeout: 12, 870 }, 871 }, 872 want: []error{errors.New("account_defaults.price_floors.fetch.period_sec should not be less than 300 seconds")}, 873 }, 874 { 875 description: "Invalid max age for fetch", 876 pf: &AccountPriceFloors{ 877 EnforceFloorsRate: 100, 878 MaxRule: 200, 879 MaxSchemaDims: 10, 880 Fetcher: AccountFloorFetch{ 881 Period: 300, 882 MaxAge: 500, 883 Timeout: 12, 884 }, 885 }, 886 want: []error{errors.New("account_defaults.price_floors.fetch.max_age_sec should not be less than 600 seconds and greater than maximum integer value")}, 887 }, 888 { 889 description: "Period is greater than max age", 890 pf: &AccountPriceFloors{ 891 EnforceFloorsRate: 100, 892 MaxRule: 200, 893 MaxSchemaDims: 10, 894 Fetcher: AccountFloorFetch{ 895 Period: 700, 896 MaxAge: 600, 897 Timeout: 12, 898 }, 899 }, 900 want: []error{errors.New("account_defaults.price_floors.fetch.period_sec should be less than account_defaults.price_floors.fetch.max_age_sec")}, 901 }, 902 { 903 description: "Invalid timeout", 904 pf: &AccountPriceFloors{ 905 EnforceFloorsRate: 100, 906 MaxRule: 200, 907 MaxSchemaDims: 10, 908 Fetcher: AccountFloorFetch{ 909 Period: 300, 910 MaxAge: 600, 911 Timeout: 4, 912 }, 913 }, 914 want: []error{errors.New("account_defaults.price_floors.fetch.timeout_ms should be between 10 to 10,000 miliseconds")}, 915 }, 916 { 917 description: "Invalid Max Rules", 918 pf: &AccountPriceFloors{ 919 EnforceFloorsRate: 100, 920 MaxRule: 200, 921 MaxSchemaDims: 10, 922 Fetcher: AccountFloorFetch{ 923 Period: 300, 924 MaxAge: 600, 925 Timeout: 12, 926 MaxRules: -2, 927 }, 928 }, 929 want: []error{errors.New("account_defaults.price_floors.fetch.max_rules should be greater than or equal to 0")}, 930 }, 931 { 932 description: "Invalid Max File size", 933 pf: &AccountPriceFloors{ 934 EnforceFloorsRate: 100, 935 MaxRule: 200, 936 MaxSchemaDims: 10, 937 Fetcher: AccountFloorFetch{ 938 Period: 300, 939 MaxAge: 600, 940 Timeout: 12, 941 MaxFileSizeKB: -1, 942 }, 943 }, 944 want: []error{errors.New("account_defaults.price_floors.fetch.max_file_size_kb should be greater than or equal to 0")}, 945 }, 946 { 947 description: "Invalid max_schema_dims", 948 pf: &AccountPriceFloors{ 949 EnforceFloorsRate: 100, 950 MaxRule: 200, 951 MaxSchemaDims: 10, 952 Fetcher: AccountFloorFetch{ 953 Period: 300, 954 MaxAge: 600, 955 Timeout: 12, 956 MaxFileSizeKB: 10, 957 MaxSchemaDims: 40, 958 }, 959 }, 960 want: []error{errors.New("account_defaults.price_floors.fetch.max_schema_dims should not be less than 0 and greater than 20")}, 961 }, 962 } 963 for _, tt := range tests { 964 t.Run(tt.description, func(t *testing.T) { 965 var errs []error 966 got := tt.pf.validate(errs) 967 assert.ElementsMatch(t, got, tt.want) 968 }) 969 } 970 } 971 972 func TestIPMaskingValidate(t *testing.T) { 973 tests := []struct { 974 name string 975 privacy AccountPrivacy 976 want []error 977 }{ 978 { 979 name: "valid", 980 privacy: AccountPrivacy{ 981 IPv4Config: IPv4{AnonKeepBits: 1}, 982 IPv6Config: IPv6{AnonKeepBits: 0}, 983 }, 984 }, 985 { 986 name: "invalid", 987 privacy: AccountPrivacy{ 988 IPv4Config: IPv4{AnonKeepBits: -100}, 989 IPv6Config: IPv6{AnonKeepBits: -200}, 990 }, 991 want: []error{ 992 errors.New("bits cannot exceed 32 in ipv4 address, or be less than 0"), 993 errors.New("bits cannot exceed 128 in ipv6 address, or be less than 0"), 994 }, 995 }, 996 { 997 name: "mixed", 998 privacy: AccountPrivacy{ 999 IPv4Config: IPv4{AnonKeepBits: 10}, 1000 IPv6Config: IPv6{AnonKeepBits: -10}, 1001 }, 1002 want: []error{ 1003 errors.New("bits cannot exceed 128 in ipv6 address, or be less than 0"), 1004 }, 1005 }, 1006 } 1007 1008 for _, tt := range tests { 1009 t.Run(tt.name, func(t *testing.T) { 1010 var errs []error 1011 errs = tt.privacy.IPv4Config.Validate(errs) 1012 errs = tt.privacy.IPv6Config.Validate(errs) 1013 assert.ElementsMatch(t, errs, tt.want) 1014 }) 1015 } 1016 }