github.com/prebid/prebid-server/v2@v2.18.0/gdpr/purpose_enforcer_test.go (about)

     1  package gdpr
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/prebid/go-gdpr/consentconstants"
     7  	"github.com/prebid/prebid-server/v2/config"
     8  	"github.com/prebid/prebid-server/v2/openrtb_ext"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  )
    12  
    13  func TestNewPurposeEnforcerBuilder(t *testing.T) {
    14  	appnexus := string(openrtb_ext.BidderAppnexus)
    15  
    16  	tests := []struct {
    17  		description        string
    18  		enforceAlgo        config.TCF2EnforcementAlgo
    19  		enforcePurpose     bool
    20  		enforceVendors     bool
    21  		basicVendorsMap    map[string]struct{}
    22  		vendorExceptionMap map[string]struct{}
    23  		purpose            consentconstants.Purpose
    24  		bidder             string
    25  		wantType           PurposeEnforcer
    26  	}{
    27  		{
    28  			description:        "purpose 1 full algo -- full enforcer returned",
    29  			enforceAlgo:        config.TCF2FullEnforcement,
    30  			enforcePurpose:     true,
    31  			enforceVendors:     true,
    32  			basicVendorsMap:    map[string]struct{}{},
    33  			vendorExceptionMap: map[string]struct{}{},
    34  			purpose:            consentconstants.Purpose(1),
    35  			bidder:             appnexus,
    36  			wantType:           &FullEnforcement{},
    37  		},
    38  		{
    39  			description:        "purpose 1 full algo, basic enforcement vendor -- full enforcer returned",
    40  			enforceAlgo:        config.TCF2FullEnforcement,
    41  			enforcePurpose:     true,
    42  			enforceVendors:     true,
    43  			basicVendorsMap:    map[string]struct{}{appnexus: {}},
    44  			vendorExceptionMap: map[string]struct{}{},
    45  			purpose:            consentconstants.Purpose(1),
    46  			bidder:             appnexus,
    47  			wantType:           &FullEnforcement{},
    48  		},
    49  		{
    50  			description:        "purpose 1 basic algo -- basic enforcer returned",
    51  			enforceAlgo:        config.TCF2BasicEnforcement,
    52  			enforcePurpose:     true,
    53  			enforceVendors:     true,
    54  			basicVendorsMap:    map[string]struct{}{},
    55  			vendorExceptionMap: map[string]struct{}{},
    56  			purpose:            consentconstants.Purpose(1),
    57  			bidder:             appnexus,
    58  			wantType:           &BasicEnforcement{},
    59  		},
    60  		{
    61  			description:        "purpose 2 full algo -- full enforcer returned",
    62  			enforceAlgo:        config.TCF2FullEnforcement,
    63  			enforcePurpose:     true,
    64  			enforceVendors:     true,
    65  			basicVendorsMap:    map[string]struct{}{},
    66  			vendorExceptionMap: map[string]struct{}{},
    67  			purpose:            consentconstants.Purpose(2),
    68  			bidder:             appnexus,
    69  			wantType:           &FullEnforcement{},
    70  		},
    71  		{
    72  			description:        "purpose 2 full algo, basic enforcement vendor -- basic enforcer returned",
    73  			enforceAlgo:        config.TCF2FullEnforcement,
    74  			enforcePurpose:     true,
    75  			enforceVendors:     true,
    76  			basicVendorsMap:    map[string]struct{}{appnexus: {}},
    77  			vendorExceptionMap: map[string]struct{}{},
    78  			purpose:            consentconstants.Purpose(2),
    79  			bidder:             appnexus,
    80  			wantType:           &BasicEnforcement{},
    81  		},
    82  		{
    83  			description:        "purpose 2 basic algo -- basic enforcer returned",
    84  			enforceAlgo:        config.TCF2BasicEnforcement,
    85  			enforcePurpose:     true,
    86  			enforceVendors:     true,
    87  			basicVendorsMap:    map[string]struct{}{},
    88  			vendorExceptionMap: map[string]struct{}{},
    89  			purpose:            consentconstants.Purpose(2),
    90  			bidder:             appnexus,
    91  			wantType:           &BasicEnforcement{},
    92  		},
    93  	}
    94  
    95  	for _, tt := range tests {
    96  		cfg := fakeTCF2ConfigReader{
    97  			enforceAlgo:                tt.enforceAlgo,
    98  			enforcePurpose:             tt.enforcePurpose,
    99  			enforceVendors:             tt.enforceVendors,
   100  			basicEnforcementVendorsMap: tt.basicVendorsMap,
   101  			vendorExceptionMap:         tt.vendorExceptionMap,
   102  		}
   103  
   104  		builder := NewPurposeEnforcerBuilder(&cfg)
   105  
   106  		enforcer1 := builder(tt.purpose, tt.bidder)
   107  		enforcer2 := builder(tt.purpose, tt.bidder)
   108  
   109  		// assert that enforcer1 and enforcer2 are same objects; enforcer2 pulled from cache
   110  		assert.Same(t, enforcer1, enforcer2, tt.description)
   111  		assert.IsType(t, tt.wantType, enforcer1, tt.description)
   112  
   113  		// assert enforcer 1 config values are properly set
   114  		switch enforcer1.(type) {
   115  		case *FullEnforcement:
   116  			{
   117  				fullEnforcer := enforcer1.(*FullEnforcement)
   118  				assert.Equal(t, fullEnforcer.cfg.PurposeID, tt.purpose, tt.description)
   119  				assert.Equal(t, fullEnforcer.cfg.EnforceAlgo, tt.enforceAlgo, tt.description)
   120  				assert.Equal(t, fullEnforcer.cfg.EnforcePurpose, tt.enforcePurpose, tt.description)
   121  				assert.Equal(t, fullEnforcer.cfg.EnforceVendors, tt.enforceVendors, tt.description)
   122  				assert.Equal(t, fullEnforcer.cfg.BasicEnforcementVendorsMap, tt.basicVendorsMap, tt.description)
   123  				assert.Equal(t, fullEnforcer.cfg.VendorExceptionMap, tt.vendorExceptionMap, tt.description)
   124  			}
   125  		case PurposeEnforcer:
   126  			{
   127  				basicEnforcer := enforcer1.(*BasicEnforcement)
   128  				assert.Equal(t, basicEnforcer.cfg.PurposeID, tt.purpose, tt.description)
   129  				assert.Equal(t, basicEnforcer.cfg.EnforceAlgo, tt.enforceAlgo, tt.description)
   130  				assert.Equal(t, basicEnforcer.cfg.EnforcePurpose, tt.enforcePurpose, tt.description)
   131  				assert.Equal(t, basicEnforcer.cfg.EnforceVendors, tt.enforceVendors, tt.description)
   132  				assert.Equal(t, basicEnforcer.cfg.BasicEnforcementVendorsMap, tt.basicVendorsMap, tt.description)
   133  				assert.Equal(t, basicEnforcer.cfg.VendorExceptionMap, tt.vendorExceptionMap, tt.description)
   134  			}
   135  		}
   136  	}
   137  }
   138  
   139  func TestNewPurposeEnforcerBuilderCaching(t *testing.T) {
   140  
   141  	bidder1 := string(openrtb_ext.BidderAppnexus)
   142  	bidder1Enforcers := make([]PurposeEnforcer, 11)
   143  	bidder2 := string(openrtb_ext.BidderIx)
   144  	bidder2Enforcers := make([]PurposeEnforcer, 11)
   145  	bidder3 := string(openrtb_ext.BidderPubmatic)
   146  	bidder3Enforcers := make([]PurposeEnforcer, 11)
   147  	bidder4 := string(openrtb_ext.BidderRubicon)
   148  	bidder4Enforcers := make([]PurposeEnforcer, 11)
   149  
   150  	cfg := fakeTCF2ConfigReader{
   151  		enforceAlgo: config.TCF2FullEnforcement,
   152  		basicEnforcementVendorsMap: map[string]struct{}{
   153  			string(bidder3): {},
   154  			string(bidder4): {},
   155  		},
   156  	}
   157  	builder := NewPurposeEnforcerBuilder(&cfg)
   158  
   159  	for i := 1; i <= 10; i++ {
   160  		bidder1Enforcers[i] = builder(consentconstants.Purpose(i), bidder1)
   161  		bidder2Enforcers[i] = builder(consentconstants.Purpose(i), bidder2)
   162  		bidder3Enforcers[i] = builder(consentconstants.Purpose(i), bidder3)
   163  		bidder4Enforcers[i] = builder(consentconstants.Purpose(i), bidder4)
   164  	}
   165  
   166  	for i := 1; i <= 10; i++ {
   167  		if i == 1 {
   168  			assert.IsType(t, bidder1Enforcers[i], &FullEnforcement{}, "purpose 1 bidder 1 enforcer is full")
   169  			assert.IsType(t, bidder3Enforcers[i], &FullEnforcement{}, "purpose 1 bidder 3 enforcer is full")
   170  
   171  			// verify cross-bidder enforcer objects for a given purpose are the same
   172  			assert.Same(t, bidder1Enforcers[i], bidder2Enforcers[i], "purpose 1 compare bidder 1 & 2 enforcers")
   173  			assert.Same(t, bidder2Enforcers[i], bidder3Enforcers[i], "purpose 1 compare bidder 2 & 3 enforcers")
   174  			assert.Same(t, bidder3Enforcers[i], bidder4Enforcers[i], "purpose 1 compare bidder 3 & 4 enforcers")
   175  
   176  			// verify cross-purpose enforcer objects are different
   177  			assert.Equal(t, bidder1Enforcers[i].(*FullEnforcement).cfg.PurposeID, consentconstants.Purpose(i), "purpose 1 bidder 1 enforcer purpose check")
   178  			assert.Equal(t, bidder2Enforcers[i].(*FullEnforcement).cfg.PurposeID, consentconstants.Purpose(i), "purpose 1 bidder 2 enforcer purpose check")
   179  			assert.Equal(t, bidder3Enforcers[i].(*FullEnforcement).cfg.PurposeID, consentconstants.Purpose(i), "purpose 1 bidder 3 enforcer purpose check")
   180  			assert.Equal(t, bidder4Enforcers[i].(*FullEnforcement).cfg.PurposeID, consentconstants.Purpose(i), "purpose 1 bidder 4 enforcer purpose check")
   181  		} else {
   182  			assert.IsType(t, bidder1Enforcers[i], &FullEnforcement{}, "purpose %d bidder 1 enforcer is full", i)
   183  			assert.IsType(t, bidder3Enforcers[i], &BasicEnforcement{}, "purpose %d bidder 3 enforcer is basic", i)
   184  
   185  			// verify some cross-bidder enforcer objects for a given purpose are the same and some are different
   186  			assert.Same(t, bidder1Enforcers[i], bidder2Enforcers[i], "purpose %d compare bidder 1 & 2 enforcers", i)
   187  			assert.NotSame(t, bidder2Enforcers[i], bidder3Enforcers[i], "purpose %d compare bidder 2 & 3 enforcers", i)
   188  			assert.Same(t, bidder3Enforcers[i], bidder4Enforcers[i], "purpose %d compare bidder 3 & 4 enforcers", i)
   189  
   190  			// verify cross-purpose enforcer objects are different
   191  			assert.Equal(t, bidder1Enforcers[i].(*FullEnforcement).cfg.PurposeID, consentconstants.Purpose(i), "purpose %d bidder 1 enforcer purpose check", i)
   192  			assert.Equal(t, bidder2Enforcers[i].(*FullEnforcement).cfg.PurposeID, consentconstants.Purpose(i), "purpose %d bidder 2 enforcer purpose check", i)
   193  			assert.Equal(t, bidder3Enforcers[i].(*BasicEnforcement).cfg.PurposeID, consentconstants.Purpose(i), "purpose %d bidder 3 enforcer purpose check", i)
   194  			assert.Equal(t, bidder4Enforcers[i].(*BasicEnforcement).cfg.PurposeID, consentconstants.Purpose(i), "purpose %d bidder 4 enforcer purpose check", i)
   195  		}
   196  	}
   197  }
   198  
   199  type fakeTCF2ConfigReader struct {
   200  	enforceAlgo                config.TCF2EnforcementAlgo
   201  	enforcePurpose             bool
   202  	enforceVendors             bool
   203  	vendorExceptionMap         map[string]struct{}
   204  	basicEnforcementVendorsMap map[string]struct{}
   205  }
   206  
   207  func (fcr *fakeTCF2ConfigReader) BasicEnforcementVendors() map[string]struct{} {
   208  	return fcr.basicEnforcementVendorsMap
   209  }
   210  func (fcr *fakeTCF2ConfigReader) FeatureOneEnforced() bool {
   211  	return false
   212  }
   213  func (fcr *fakeTCF2ConfigReader) FeatureOneVendorException(openrtb_ext.BidderName) bool {
   214  	return false
   215  }
   216  func (fcr *fakeTCF2ConfigReader) ChannelEnabled(config.ChannelType) bool {
   217  	return false
   218  }
   219  func (fcr *fakeTCF2ConfigReader) IsEnabled() bool {
   220  	return false
   221  }
   222  func (fcr *fakeTCF2ConfigReader) PurposeEnforced(purpose consentconstants.Purpose) bool {
   223  	return fcr.enforcePurpose
   224  }
   225  func (fcr *fakeTCF2ConfigReader) PurposeEnforcementAlgo(purpose consentconstants.Purpose) config.TCF2EnforcementAlgo {
   226  	return fcr.enforceAlgo
   227  }
   228  func (fcr *fakeTCF2ConfigReader) PurposeEnforcingVendors(purpose consentconstants.Purpose) bool {
   229  	return fcr.enforceVendors
   230  }
   231  func (fcr *fakeTCF2ConfigReader) PurposeVendorExceptions(purpose consentconstants.Purpose) map[string]struct{} {
   232  	return fcr.vendorExceptionMap
   233  }
   234  func (fcr *fakeTCF2ConfigReader) PurposeOneTreatmentEnabled() bool {
   235  	return false
   236  }
   237  func (fcr *fakeTCF2ConfigReader) PurposeOneTreatmentAccessAllowed() bool {
   238  	return false
   239  }