github.com/prebid/prebid-server@v0.275.0/amp/parse_test.go (about)

     1  package amp
     2  
     3  import (
     4  	"net/http"
     5  	"testing"
     6  
     7  	"github.com/prebid/openrtb/v19/openrtb2"
     8  	"github.com/prebid/prebid-server/errortypes"
     9  	"github.com/prebid/prebid-server/privacy"
    10  	"github.com/prebid/prebid-server/privacy/ccpa"
    11  	"github.com/prebid/prebid-server/privacy/gdpr"
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  func TestParseParams(t *testing.T) {
    16  	var expectedTimeout uint64 = 42
    17  
    18  	testCases := []struct {
    19  		description    string
    20  		query          string
    21  		expectedParams Params
    22  		expectedError  string
    23  	}{
    24  		{
    25  			description:   "Empty",
    26  			query:         "",
    27  			expectedError: "AMP requests require an AMP tag_id",
    28  		},
    29  		{
    30  			description: "All Fields",
    31  			// targeting data is encoded string that looks like this: {"gam-key1":"val1","gam-key2":"val2"}
    32  			query: "tag_id=anyTagID&account=anyAccount&curl=anyCurl&consent_string=anyConsent&debug=1&__amp_source_origin=anyOrigin" +
    33  				"&slot=anySlot&timeout=42&h=1&w=2&oh=3&ow=4&ms=10x11,12x13&targeting=%7B%22gam-key1%22%3A%22val1%22%2C%22gam-key2%22%3A%22val2%22%7D&trace=basic",
    34  			expectedParams: Params{
    35  				Account:         "anyAccount",
    36  				CanonicalURL:    "anyCurl",
    37  				Consent:         "anyConsent",
    38  				Debug:           true,
    39  				Origin:          "anyOrigin",
    40  				Slot:            "anySlot",
    41  				StoredRequestID: "anyTagID",
    42  				Timeout:         &expectedTimeout,
    43  				Size: Size{
    44  					Height:         1,
    45  					OverrideHeight: 3,
    46  					OverrideWidth:  4,
    47  					Width:          2,
    48  					Multisize: []openrtb2.Format{
    49  						{W: 10, H: 11}, {W: 12, H: 13},
    50  					},
    51  				},
    52  				Targeting: `{"gam-key1":"val1","gam-key2":"val2"}`,
    53  				Trace:     "basic",
    54  			},
    55  		},
    56  		{
    57  			description:    "Integer Values Ignored If Invalid",
    58  			query:          "tag_id=anyTagID&h=invalid&w=invalid&oh=invalid&ow=invalid&ms=invalid",
    59  			expectedParams: Params{StoredRequestID: "anyTagID"},
    60  		},
    61  		{
    62  			description:    "consent_string Preferred Over gdpr_consent",
    63  			query:          "tag_id=anyTagID&consent_string=consent1&gdpr_consent=consent2",
    64  			expectedParams: Params{StoredRequestID: "anyTagID", Consent: "consent1"},
    65  		},
    66  		{
    67  			description:    "consent_string Preferred Over gdpr_consent - Order Doesn't Matter",
    68  			query:          "tag_id=anyTagID&gdpr_consent=consent2&consent_string=consent1",
    69  			expectedParams: Params{StoredRequestID: "anyTagID", Consent: "consent1"},
    70  		},
    71  		{
    72  			description:    "Just gdpr_consent",
    73  			query:          "tag_id=anyTagID&gdpr_consent=consent2",
    74  			expectedParams: Params{StoredRequestID: "anyTagID", Consent: "consent2"},
    75  		},
    76  		{
    77  			description:    "Debug 0",
    78  			query:          "tag_id=anyTagID&debug=0",
    79  			expectedParams: Params{StoredRequestID: "anyTagID", Debug: false},
    80  		},
    81  		{
    82  			description:    "Debug Ignored If Invalid",
    83  			query:          "tag_id=anyTagID&debug=invalid",
    84  			expectedParams: Params{StoredRequestID: "anyTagID", Debug: false},
    85  		},
    86  	}
    87  
    88  	for _, test := range testCases {
    89  		httpRequest, err := http.NewRequest("GET", "http://any.url/anypage?"+test.query, nil)
    90  		assert.NoError(t, err, test.description+":request")
    91  
    92  		params, err := ParseParams(httpRequest)
    93  		assert.Equal(t, test.expectedParams, params, test.description+":params")
    94  		if test.expectedError == "" {
    95  			assert.NoError(t, err, test.description+":err")
    96  		} else {
    97  			assert.EqualError(t, err, test.expectedError)
    98  		}
    99  	}
   100  }
   101  
   102  func TestParseIntPtr(t *testing.T) {
   103  	var boolZero uint64 = 0
   104  	var boolOne uint64 = 1
   105  
   106  	type testResults struct {
   107  		intPtr *uint64
   108  		err    bool
   109  	}
   110  
   111  	testCases := []struct {
   112  		desc     string
   113  		input    string
   114  		expected testResults
   115  	}{
   116  		{
   117  			desc:  "Input is an empty string: expect nil pointer and error",
   118  			input: "",
   119  			expected: testResults{
   120  				intPtr: nil,
   121  				err:    true,
   122  			},
   123  		},
   124  		{
   125  			desc:  "Input is negative number: expect a nil pointer and error",
   126  			input: "-1",
   127  			expected: testResults{
   128  				intPtr: nil,
   129  				err:    true,
   130  			},
   131  		},
   132  		{
   133  			desc:  "Input is a string depicting a zero value: expect a reference pointing to zero value, no error",
   134  			input: "0",
   135  			expected: testResults{
   136  				intPtr: &boolZero,
   137  				err:    false,
   138  			},
   139  		},
   140  		{
   141  			desc:  "Input is a string depicting a value of 1: expect a reference pointing to the value of 1 and no error",
   142  			input: "1",
   143  			expected: testResults{
   144  				intPtr: &boolOne,
   145  				err:    false,
   146  			},
   147  		},
   148  	}
   149  	for _, tc := range testCases {
   150  		resultingIntPtr, resultingErr := parseIntPtr(tc.input)
   151  
   152  		assert.Equal(t, tc.expected.intPtr, resultingIntPtr, tc.desc)
   153  		if tc.expected.err {
   154  			assert.Error(t, resultingErr, tc.desc)
   155  		} else {
   156  			assert.NoError(t, resultingErr, tc.desc)
   157  		}
   158  	}
   159  }
   160  
   161  func TestParseBoolPtr(t *testing.T) {
   162  	boolTrue := true
   163  	boolFalse := false
   164  
   165  	type testResults struct {
   166  		boolPtr *bool
   167  		err     bool
   168  	}
   169  
   170  	testCases := []struct {
   171  		desc     string
   172  		input    string
   173  		expected testResults
   174  	}{
   175  		{
   176  			desc:  "Input is an empty string: expect nil pointer and error",
   177  			input: "",
   178  			expected: testResults{
   179  				boolPtr: nil,
   180  				err:     true,
   181  			},
   182  		},
   183  		{
   184  			desc:  "Input is neither true nor false: expect a nil pointer and error",
   185  			input: "other",
   186  			expected: testResults{
   187  				boolPtr: nil,
   188  				err:     true,
   189  			},
   190  		},
   191  		{
   192  			desc:  "Input is the word 'false', expect a reference pointing to false value",
   193  			input: "false",
   194  			expected: testResults{
   195  				boolPtr: &boolFalse,
   196  				err:     false,
   197  			},
   198  		},
   199  		{
   200  			desc:  "Input is the word 'true', expect a reference pointing to true value",
   201  			input: "true",
   202  			expected: testResults{
   203  				boolPtr: &boolTrue,
   204  				err:     false,
   205  			},
   206  		},
   207  	}
   208  	for _, tc := range testCases {
   209  		resultingBoolPtr, resultingErr := parseBoolPtr(tc.input)
   210  
   211  		assert.Equal(t, tc.expected.boolPtr, resultingBoolPtr, tc.desc)
   212  		if tc.expected.err {
   213  			assert.Error(t, resultingErr, tc.desc)
   214  		} else {
   215  			assert.NoError(t, resultingErr, tc.desc)
   216  		}
   217  	}
   218  }
   219  
   220  // TestPrivacyReader asserts the ReadPolicy scenarios
   221  func TestPrivacyReader(t *testing.T) {
   222  	int8Zero := int8(0)
   223  	int8One := int8(1)
   224  	boolTrue := true
   225  	boolFalse := false
   226  
   227  	type testInput struct {
   228  		ampParams Params
   229  	}
   230  	type expectedResults struct {
   231  		policyWriter privacy.PolicyWriter
   232  		warning      error
   233  	}
   234  	type testCase struct {
   235  		desc     string
   236  		in       testInput
   237  		expected expectedResults
   238  	}
   239  
   240  	testGroups := []struct {
   241  		groupDesc string
   242  		tests     []testCase
   243  	}{
   244  		{
   245  			groupDesc: "No consent string",
   246  			tests: []testCase{
   247  				{
   248  					desc:     "Params comes with an empty consent string, expect nil policy writer. No warning returned",
   249  					expected: expectedResults{policyWriter: privacy.NilPolicyWriter{}, warning: nil},
   250  				},
   251  			},
   252  		},
   253  		{
   254  			groupDesc: "TCF1",
   255  			tests: []testCase{
   256  				{
   257  					desc: "Consent type TCF1: expect nil policy writer. Warning is returned",
   258  					in: testInput{
   259  						ampParams: Params{Consent: "VALID_TCF1_CONSENT", ConsentType: ConsentTCF1},
   260  					},
   261  					expected: expectedResults{
   262  						policyWriter: privacy.NilPolicyWriter{},
   263  						warning:      &errortypes.Warning{Message: "TCF1 consent is deprecated and no longer supported.", WarningCode: errortypes.InvalidPrivacyConsentWarningCode},
   264  					},
   265  				},
   266  			},
   267  		},
   268  		{
   269  			groupDesc: "ConsentNone. In order to be backwards compatible, we'll guess what consent string this is",
   270  			tests: []testCase{
   271  				{
   272  					desc: "No consent type was specified and invalid consent string provided: expect nil policy writer and a warning",
   273  					in: testInput{
   274  						ampParams: Params{Consent: "NOT_CCPA_NOR_GDPR_TCF2"},
   275  					},
   276  					expected: expectedResults{
   277  						policyWriter: privacy.NilPolicyWriter{},
   278  						warning:      &errortypes.Warning{Message: "Consent string 'NOT_CCPA_NOR_GDPR_TCF2' is not recognized as one of the supported formats CCPA or TCF2.", WarningCode: errortypes.InvalidPrivacyConsentWarningCode},
   279  					},
   280  				},
   281  				{
   282  					desc: "No consent type specified but query params come with a valid CCPA consent string: expect a CCPA consent writer and no error nor warning",
   283  					in: testInput{
   284  						ampParams: Params{Consent: "1YYY"},
   285  					},
   286  					expected: expectedResults{
   287  						policyWriter: ccpa.ConsentWriter{"1YYY"},
   288  						warning:      nil,
   289  					},
   290  				},
   291  				{
   292  					desc: "No consent type, valid CCPA consent string and gdpr_applies set to true: expect a CCPA consent writer and a warning",
   293  					in: testInput{
   294  						ampParams: Params{Consent: "1YYY", GdprApplies: &boolTrue},
   295  					},
   296  					expected: expectedResults{
   297  						policyWriter: ccpa.ConsentWriter{"1YYY"},
   298  						warning:      &errortypes.Warning{Message: "AMP request gdpr_applies value was ignored because provided consent string is a CCPA consent string", WarningCode: errortypes.InvalidPrivacyConsentWarningCode},
   299  					},
   300  				},
   301  				{
   302  					desc: "No consent type, valid GDPR consent string and gdpr_applies not set: expect a GDPR consent writer and no error nor warning",
   303  					in: testInput{
   304  						ampParams: Params{Consent: "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA"},
   305  					},
   306  					expected: expectedResults{
   307  						policyWriter: gdpr.ConsentWriter{"CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", &int8One},
   308  						warning:      nil,
   309  					},
   310  				},
   311  			},
   312  		},
   313  		{
   314  			groupDesc: "Unrecognized consent type. In order to be backwards compatible, we'll guess what consent string type it is",
   315  			tests: []testCase{
   316  				{
   317  					desc: "Unrecognized consent type was specified and invalid consent string provided: expect nil policy writer and a warning",
   318  					in: testInput{
   319  						ampParams: Params{ConsentType: 101, Consent: "NOT_CCPA_NOR_GDPR_TCF2"},
   320  					},
   321  					expected: expectedResults{
   322  						policyWriter: privacy.NilPolicyWriter{},
   323  						warning:      &errortypes.Warning{Message: "Consent string 'NOT_CCPA_NOR_GDPR_TCF2' is not recognized as one of the supported formats CCPA or TCF2.", WarningCode: errortypes.InvalidPrivacyConsentWarningCode},
   324  					},
   325  				},
   326  				{
   327  					desc: "Unrecognized consent type specified but query params come with a valid CCPA consent string: expect a CCPA consent writer and no error nor warning",
   328  					in: testInput{
   329  						ampParams: Params{ConsentType: 101, Consent: "1YYY"},
   330  					},
   331  					expected: expectedResults{
   332  						policyWriter: ccpa.ConsentWriter{"1YYY"},
   333  						warning:      nil,
   334  					},
   335  				},
   336  				{
   337  					desc: "Unrecognized consent type, valid CCPA consent string and gdpr_applies set to true: expect a CCPA consent writer and a warning",
   338  					in: testInput{
   339  						ampParams: Params{ConsentType: 101, Consent: "1YYY", GdprApplies: &boolTrue},
   340  					},
   341  					expected: expectedResults{
   342  						policyWriter: ccpa.ConsentWriter{"1YYY"},
   343  						warning:      &errortypes.Warning{Message: "AMP request gdpr_applies value was ignored because provided consent string is a CCPA consent string", WarningCode: errortypes.InvalidPrivacyConsentWarningCode},
   344  					},
   345  				},
   346  				{
   347  					desc: "Unrecognized consent type, valid TCF2 consent string and gdpr_applies not set: expect GDPR consent writer and no error nor warning",
   348  					in: testInput{
   349  						ampParams: Params{ConsentType: 101, Consent: "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA"},
   350  					},
   351  					expected: expectedResults{
   352  						policyWriter: gdpr.ConsentWriter{"CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", &int8One},
   353  						warning:      nil,
   354  					},
   355  				},
   356  			},
   357  		},
   358  		{
   359  			groupDesc: "consent type TCF2. Return a valid GDPR consent writer in all scenarios.",
   360  			tests: []testCase{
   361  				{
   362  					desc: "GDPR consent string is invalid, but consent type is TCF2: return a valid GDPR writer and warn about the GDPR string being invalid",
   363  					in: testInput{
   364  						ampParams: Params{Consent: "INVALID_GDPR", ConsentType: ConsentTCF2, GdprApplies: nil},
   365  					},
   366  					expected: expectedResults{
   367  						policyWriter: gdpr.ConsentWriter{"INVALID_GDPR", &int8One},
   368  						warning:      &errortypes.Warning{Message: "Consent string 'INVALID_GDPR' is not a valid TCF2 consent string.", WarningCode: errortypes.InvalidPrivacyConsentWarningCode},
   369  					},
   370  				},
   371  				{
   372  					desc: "GDPR consent string is invalid, consent type is TCF2, gdpr_applies is set to true: return a valid GDPR writer and warn about the GDPR string being invalid",
   373  					in: testInput{
   374  						ampParams: Params{Consent: "INVALID_GDPR", ConsentType: ConsentTCF2, GdprApplies: &boolFalse},
   375  					},
   376  					expected: expectedResults{
   377  						policyWriter: gdpr.ConsentWriter{"INVALID_GDPR", &int8Zero},
   378  						warning:      &errortypes.Warning{Message: "Consent string 'INVALID_GDPR' is not a valid TCF2 consent string.", WarningCode: errortypes.InvalidPrivacyConsentWarningCode},
   379  					},
   380  				},
   381  				{
   382  					desc: "Valid GDPR consent string, gdpr_applies is set to false, return a valid GDPR writer, no warning",
   383  					in: testInput{
   384  						ampParams: Params{Consent: "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", ConsentType: ConsentTCF2, GdprApplies: &boolFalse},
   385  					},
   386  					expected: expectedResults{
   387  						policyWriter: gdpr.ConsentWriter{"CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", &int8Zero},
   388  						warning:      nil,
   389  					},
   390  				},
   391  				{
   392  					desc: "Valid GDPR consent string, gdpr_applies is set to true, return a valid GDPR writer and no warning",
   393  					in: testInput{
   394  						ampParams: Params{Consent: "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", ConsentType: ConsentTCF2, GdprApplies: &boolTrue},
   395  					},
   396  					expected: expectedResults{
   397  						policyWriter: gdpr.ConsentWriter{"CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", &int8One},
   398  						warning:      nil,
   399  					},
   400  				},
   401  				{
   402  					desc: "Valid GDPR consent string, return a valid GDPR writer and no warning",
   403  					in: testInput{
   404  						ampParams: Params{Consent: "CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", ConsentType: ConsentTCF2},
   405  					},
   406  					expected: expectedResults{
   407  						policyWriter: gdpr.ConsentWriter{"CPdiPIJPdiPIJACABBENAzCv_____3___wAAAQNd_X9cAAAAAAAA", &int8One},
   408  						warning:      nil,
   409  					},
   410  				},
   411  			},
   412  		},
   413  		{
   414  			groupDesc: "consent type CCPA. Return a valid CCPA consent writer in all scenarios.",
   415  			tests: []testCase{
   416  				{
   417  					desc: "CCPA consent string is invalid: return a valid writer a warning about the string being invalid",
   418  					in: testInput{
   419  						ampParams: Params{Consent: "XXXX", ConsentType: ConsentUSPrivacy},
   420  					},
   421  					expected: expectedResults{
   422  						policyWriter: ccpa.ConsentWriter{"XXXX"},
   423  						warning:      &errortypes.Warning{Message: "Consent string 'XXXX' is not a valid CCPA consent string.", WarningCode: errortypes.InvalidPrivacyConsentWarningCode},
   424  					},
   425  				},
   426  				{
   427  					desc: "Valid CCPA consent string, gdpr_applies is set to true: return a valid GDPR writer and warn about the gdpr_applies value.",
   428  					in: testInput{
   429  						ampParams: Params{Consent: "1YYY", ConsentType: ConsentUSPrivacy, GdprApplies: &boolTrue},
   430  					},
   431  					expected: expectedResults{
   432  						policyWriter: ccpa.ConsentWriter{"1YYY"},
   433  						warning:      &errortypes.Warning{Message: "AMP request gdpr_applies value was ignored because provided consent string is a CCPA consent string", WarningCode: errortypes.InvalidPrivacyConsentWarningCode},
   434  					},
   435  				},
   436  				{
   437  					desc: "Valid CCPA consent string, return a valid GDPR writer and no warning",
   438  					in: testInput{
   439  						ampParams: Params{Consent: "1YYY", ConsentType: ConsentUSPrivacy},
   440  					},
   441  					expected: expectedResults{
   442  						policyWriter: ccpa.ConsentWriter{"1YYY"},
   443  						warning:      nil,
   444  					},
   445  				},
   446  			},
   447  		},
   448  	}
   449  	for _, group := range testGroups {
   450  		for _, tc := range group.tests {
   451  			actualPolicyWriter, actualErr := ReadPolicy(tc.in.ampParams, true)
   452  
   453  			assert.Equal(t, tc.expected.policyWriter, actualPolicyWriter, tc.desc)
   454  			assert.Equal(t, tc.expected.warning, actualErr, tc.desc)
   455  		}
   456  	}
   457  }
   458  
   459  func TestBuildGdprTCF2ConsentWriter(t *testing.T) {
   460  	int8Zero := int8(0)
   461  	int8One := int8(1)
   462  	boolTrue := true
   463  	boolFalse := false
   464  	consentString := "CONSENT"
   465  
   466  	testCases := []struct {
   467  		desc           string
   468  		inParams       Params
   469  		expectedWriter gdpr.ConsentWriter
   470  	}{
   471  		{
   472  			desc:           "gdpr_applies not set",
   473  			inParams:       Params{Consent: consentString},
   474  			expectedWriter: gdpr.ConsentWriter{consentString, &int8One},
   475  		},
   476  		{
   477  			desc:           "gdpr_applies set to false",
   478  			inParams:       Params{Consent: consentString, GdprApplies: &boolFalse},
   479  			expectedWriter: gdpr.ConsentWriter{consentString, &int8Zero},
   480  		},
   481  		{
   482  			desc:           "gdpr_applies set to true",
   483  			inParams:       Params{Consent: consentString, GdprApplies: &boolTrue},
   484  			expectedWriter: gdpr.ConsentWriter{consentString, &int8One},
   485  		},
   486  	}
   487  	for _, tc := range testCases {
   488  		actualPolicyWriter := buildGdprTCF2ConsentWriter(tc.inParams)
   489  		assert.Equal(t, tc.expectedWriter, actualPolicyWriter, tc.desc)
   490  	}
   491  }
   492  
   493  func TestParseMultisize(t *testing.T) {
   494  	testCases := []struct {
   495  		description     string
   496  		multisize       string
   497  		expectedFormats []openrtb2.Format
   498  	}{
   499  		{
   500  			description:     "Empty",
   501  			multisize:       "",
   502  			expectedFormats: nil,
   503  		},
   504  		{
   505  			description:     "One",
   506  			multisize:       "1x2",
   507  			expectedFormats: []openrtb2.Format{{W: 1, H: 2}},
   508  		},
   509  		{
   510  			description:     "Many",
   511  			multisize:       "1x2,3x4",
   512  			expectedFormats: []openrtb2.Format{{W: 1, H: 2}, {W: 3, H: 4}},
   513  		},
   514  		{
   515  			// Existing Behavior: The " 3" token in the second size is parsed as 0.
   516  			description:     "Many With Space - Quirky Result",
   517  			multisize:       "1x2, 3x4",
   518  			expectedFormats: []openrtb2.Format{{W: 1, H: 2}, {W: 0, H: 4}},
   519  		},
   520  		{
   521  			description:     "One - Zero Size - Ignored",
   522  			multisize:       "0x0",
   523  			expectedFormats: nil,
   524  		},
   525  		{
   526  			description:     "Many - Zero Size - All Ignored",
   527  			multisize:       "0x0,3x4",
   528  			expectedFormats: nil,
   529  		},
   530  		{
   531  			description:     "One - Extra Dimension - Ignored",
   532  			multisize:       "1x2x3",
   533  			expectedFormats: nil,
   534  		},
   535  		{
   536  			description:     "Many - Extra Dimension - All Ignored",
   537  			multisize:       "1x2x3,4x5",
   538  			expectedFormats: nil,
   539  		},
   540  		{
   541  			description:     "One - Invalid Values - Ignored",
   542  			multisize:       "INVALIDxINVALID",
   543  			expectedFormats: nil,
   544  		},
   545  		{
   546  			description:     "Many - Invalid Values - All Ignored",
   547  			multisize:       "1x2,INVALIDxINVALID",
   548  			expectedFormats: nil,
   549  		},
   550  		{
   551  			description:     "One - No Pair - Ignored",
   552  			multisize:       "INVALID",
   553  			expectedFormats: nil,
   554  		},
   555  		{
   556  			description:     "Many - No Pair - All Ignored",
   557  			multisize:       "1x2,INVALID",
   558  			expectedFormats: nil,
   559  		},
   560  	}
   561  
   562  	for _, test := range testCases {
   563  		result := parseMultisize(test.multisize)
   564  		assert.ElementsMatch(t, test.expectedFormats, result, test.description)
   565  	}
   566  }
   567  
   568  func TestParseGdprApplies(t *testing.T) {
   569  	gdprAppliesFalse := false
   570  	gdprAppliesTrue := true
   571  
   572  	testCases := []struct {
   573  		desc              string
   574  		inGdprApplies     *bool
   575  		expectRegsExtGdpr int8
   576  	}{
   577  		{
   578  			desc:              "gdprApplies was not set and defaulted to nil, expect 0",
   579  			inGdprApplies:     nil,
   580  			expectRegsExtGdpr: int8(0),
   581  		},
   582  		{
   583  			desc:              "gdprApplies isn't nil and is set to false, expect a value of 0",
   584  			inGdprApplies:     &gdprAppliesFalse,
   585  			expectRegsExtGdpr: int8(0),
   586  		},
   587  		{
   588  			desc:              "gdprApplies isn't nil and is set to true, expect a value of 1",
   589  			inGdprApplies:     &gdprAppliesTrue,
   590  			expectRegsExtGdpr: int8(1),
   591  		},
   592  	}
   593  	for _, tc := range testCases {
   594  		assert.Equal(t, tc.expectRegsExtGdpr, parseGdprApplies(tc.inGdprApplies), tc.desc)
   595  	}
   596  }