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