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  }