github.com/prebid/prebid-server/v2@v2.18.0/gdpr/full_enforcement_test.go (about) 1 package gdpr 2 3 import ( 4 "testing" 5 6 "github.com/prebid/go-gdpr/consentconstants" 7 "github.com/prebid/go-gdpr/vendorconsent" 8 tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2" 9 "github.com/prebid/go-gdpr/vendorlist" 10 "github.com/prebid/go-gdpr/vendorlist2" 11 "github.com/prebid/prebid-server/v2/openrtb_ext" 12 "github.com/prebid/prebid-server/v2/util/jsonutil" 13 14 "github.com/stretchr/testify/assert" 15 ) 16 17 func TestLegalBasisWithPubRestrictionAllowNone(t *testing.T) { 18 var ( 19 appnexus = string(openrtb_ext.BidderAppnexus) 20 appnexusID = uint16(32) 21 ) 22 23 NoConsentsWithP1P2P3V32RestrictionAllowNone := "CPfMKEAPfMKEAAAAAAENCgCAAAAAAAAAAAAAAQAAAAAAAIAAAAAAAGCAAgAgCAAQAQBgAIAIAAAA" 24 P1P2P3PurposeConsentAndV32VendorConsentWithP1P2P3V32RestrictionAllowNone := "CPfMKEAPfMKEAAAAAAENCgCAAOAAAAAAAAAAAQAAAAAEAIAAAAAAAGCAAgAgCAAQAQBgAIAIAAAA" 25 26 tests := []struct { 27 description string 28 config purposeConfig 29 consent string 30 wantConsentPurposeResult bool 31 wantLIPurposeResult bool 32 wantFlexPurposeResult bool 33 }{ 34 { 35 description: "enforce purpose & vendors off", 36 config: purposeConfig{ 37 EnforcePurpose: false, 38 EnforceVendors: false, 39 }, 40 consent: NoConsentsWithP1P2P3V32RestrictionAllowNone, 41 wantConsentPurposeResult: false, 42 wantLIPurposeResult: false, 43 wantFlexPurposeResult: false, 44 }, 45 { 46 description: "enforce purpose & vendors on, bidder is a vendor exception", 47 config: purposeConfig{ 48 EnforcePurpose: true, 49 EnforceVendors: true, 50 VendorExceptionMap: map[string]struct{}{appnexus: {}}, 51 }, 52 consent: NoConsentsWithP1P2P3V32RestrictionAllowNone, 53 wantConsentPurposeResult: false, 54 wantLIPurposeResult: false, 55 wantFlexPurposeResult: false, 56 }, 57 { 58 description: "enforce purpose & vendors on, purpose consent Y, vendor consent Y", 59 config: purposeConfig{ 60 EnforcePurpose: true, 61 EnforceVendors: true, 62 }, 63 consent: P1P2P3PurposeConsentAndV32VendorConsentWithP1P2P3V32RestrictionAllowNone, 64 wantConsentPurposeResult: false, 65 wantLIPurposeResult: false, 66 wantFlexPurposeResult: false, 67 }, 68 } 69 70 for _, tt := range tests { 71 // convert consent string to TCF2 object 72 parsedConsent, err := vendorconsent.ParseString(tt.consent) 73 if err != nil { 74 t.Fatalf("Failed to parse consent %s: %s\n", tt.consent, tt.description) 75 } 76 consentMeta, ok := parsedConsent.(tcf2.ConsentMetadata) 77 if !ok { 78 t.Fatalf("Failed to convert consent %s: %s\n", tt.consent, tt.description) 79 } 80 81 vendor := getVendorList(t).Vendor(appnexusID) 82 vendorInfo := VendorInfo{vendorID: appnexusID, vendor: vendor} 83 enforcer := FullEnforcement{cfg: tt.config} 84 85 enforcer.cfg.PurposeID = consentconstants.Purpose(1) 86 consentPurposeResult := enforcer.LegalBasis(vendorInfo, appnexus, consentMeta, Overrides{}) 87 assert.Equal(t, tt.wantConsentPurposeResult, consentPurposeResult, tt.description+" -- GVL consent purpose") 88 89 enforcer.cfg.PurposeID = consentconstants.Purpose(2) 90 LIPurposeresult := enforcer.LegalBasis(vendorInfo, appnexus, consentMeta, Overrides{}) 91 assert.Equal(t, tt.wantLIPurposeResult, LIPurposeresult, tt.description+" -- GVL LI purpose") 92 93 enforcer.cfg.PurposeID = consentconstants.Purpose(3) 94 flexPurposeResult := enforcer.LegalBasis(vendorInfo, appnexus, consentMeta, Overrides{}) 95 assert.Equal(t, tt.wantFlexPurposeResult, flexPurposeResult, tt.description+" -- GVL flex purpose") 96 } 97 } 98 99 func TestLegalBasisWithNoPubRestrictionsAndWithPubRestrictionAllowAll(t *testing.T) { 100 var ( 101 appnexus = string(openrtb_ext.BidderAppnexus) 102 appnexusID = uint16(32) 103 ) 104 105 NoConsents := "CPfCRQAPfCRQAAAAAAENCgCAAAAAAAAAAAAAAAAAAAAA" 106 P1P2P3PurposeConsent := "CPfCRQAPfCRQAAAAAAENCgCAAOAAAAAAAAAAAAAAAAAA" 107 P1P2P3PurposeLI := "CPfCRQAPfCRQAAAAAAENCgCAAAAAAOAAAAAAAAAAAAAA" 108 V32VendorConsent := "CPfCRQAPfCRQAAAAAAENCgCAAAAAAAAAAAAAAQAAAAAEAAAAAAAA" 109 V32VendorLI := "CPfCRQAPfCRQAAAAAAENCgCAAAAAAAAAAAAAAQAAAAAAAIAAAAACAAAA" 110 P1P2P3PurposeConsentAndV32VendorConsent := "CPfCRQAPfCRQAAAAAAENCgCAAOAAAAAAAAAAAQAAAAAEAIAAAAAAAAAA" 111 P1P2P3PurposeLIAndV32VendorLI := "CPfCRQAPfCRQAAAAAAENCgCAAAAAAOAAAAAAAQAAAAAAAIAAAAACAAAA" 112 113 NoConsentsWithP1P2P3V32RestrictionAllowAll := "CPfMKEAPfMKEAAAAAAENCgCAAAAAAAAAAAAAAQAAAAAAAIAAAAAAAGDgAgAgCwAQAQB4AIAIAAAA" 114 P1P2P3PurposeConsentWithP1P2P3V32RestrictionAllowAll := "CPfMKEAPfMKEAAAAAAENCgCAAOAAAAAAAAAAAQAAAAAAAIAAAAAAAGDgAgAgCwAQAQB4AIAIAAAA" 115 P1P2P3PurposeLIWithP1P2P3V32RestrictionAllowAll := "CPfMKEAPfMKEAAAAAAENCgCAAAAAAOAAAAAAAQAAAAAAAIAAAAAAAGDgAgAgCwAQAQB4AIAIAAAA" 116 V32VendorConsentWithP1P2P3V32RestrictionAllowAll := "CPfMKEAPfMKEAAAAAAENCgCAAAAAAAAAAAAAAQAAAAAEAIAAAAAAAGDgAgAgCwAQAQB4AIAIAAAA" 117 V32VendorLIWithP1P2P3V32RestrictionAllowAll := "CPfMKEAPfMKEAAAAAAENCgCAAAAAAAAAAAAAAQAAAAAAAIAAAAACAGDgAgAgCwAQAQB4AIAIAAAA" 118 P1P2P3PurposeConsentAndV32VendorConsentWithP1P2P3V32RestrictionAllowAll := "CPfMKEAPfMKEAAAAAAENCgCAAOAAAAAAAAAAAQAAAAAEAIAAAAAAAGDgAgAgCwAQAQB4AIAIAAAA" 119 P1P2P3PurposeLIAndV32VendorLIWithP1P2P3V32RestrictionAllowAll := "CPfMKEAPfMKEAAAAAAENCgCAAAAAAOAAAAAAAQAAAAAAAIAAAAACAGDgAgAgCwAQAQB4AIAIAAAA" 120 121 tests := []struct { 122 description string 123 config purposeConfig 124 consentNoPubRestriction string 125 consentWithPubRestriction string 126 overrides Overrides 127 wantConsentPurposeResult bool 128 wantLIPurposeResult bool 129 wantFlexPurposeResult bool 130 }{ 131 { 132 description: "enforce purpose & vendors off", 133 config: purposeConfig{ 134 EnforcePurpose: false, 135 EnforceVendors: false, 136 }, 137 consentNoPubRestriction: NoConsents, 138 consentWithPubRestriction: NoConsentsWithP1P2P3V32RestrictionAllowAll, 139 wantConsentPurposeResult: true, 140 wantLIPurposeResult: true, 141 wantFlexPurposeResult: true, 142 }, 143 { 144 description: "enforce purpose on, purpose consent N, legit interest N", 145 config: purposeConfig{ 146 EnforcePurpose: true, 147 }, 148 consentNoPubRestriction: NoConsents, 149 consentWithPubRestriction: NoConsentsWithP1P2P3V32RestrictionAllowAll, 150 wantConsentPurposeResult: false, 151 wantLIPurposeResult: false, 152 wantFlexPurposeResult: false, 153 }, 154 { 155 description: "enforce purpose on, purpose consent Y", 156 config: purposeConfig{ 157 EnforcePurpose: true, 158 }, 159 consentNoPubRestriction: P1P2P3PurposeConsent, 160 consentWithPubRestriction: P1P2P3PurposeConsentWithP1P2P3V32RestrictionAllowAll, 161 wantConsentPurposeResult: true, 162 wantLIPurposeResult: false, 163 wantFlexPurposeResult: true, 164 }, 165 { 166 description: "enforce purpose on, legit interest Y", 167 config: purposeConfig{ 168 EnforcePurpose: true, 169 }, 170 consentNoPubRestriction: P1P2P3PurposeLI, 171 consentWithPubRestriction: P1P2P3PurposeLIWithP1P2P3V32RestrictionAllowAll, 172 wantConsentPurposeResult: false, 173 wantLIPurposeResult: true, 174 wantFlexPurposeResult: true, 175 }, 176 { 177 description: "enforce purpose on, purpose consent Y, enforce vendors off but overrides treats it as on", 178 config: purposeConfig{ 179 EnforcePurpose: true, 180 }, 181 consentNoPubRestriction: P1P2P3PurposeConsent, 182 consentWithPubRestriction: P1P2P3PurposeConsentWithP1P2P3V32RestrictionAllowAll, 183 overrides: Overrides{enforceVendors: true}, 184 wantConsentPurposeResult: false, 185 wantLIPurposeResult: false, 186 wantFlexPurposeResult: false, 187 }, 188 { 189 description: "enforce purpose on, purpose consent Y, vendor consent Y, enforce vendors off but overrides treats it as on", 190 config: purposeConfig{ 191 EnforcePurpose: true, 192 }, 193 consentNoPubRestriction: P1P2P3PurposeConsentAndV32VendorConsent, 194 consentWithPubRestriction: P1P2P3PurposeConsentAndV32VendorConsentWithP1P2P3V32RestrictionAllowAll, 195 overrides: Overrides{enforceVendors: true}, 196 wantConsentPurposeResult: true, 197 wantLIPurposeResult: false, 198 wantFlexPurposeResult: true, 199 }, 200 { 201 description: "enforce vendors on, vendor consent N, vendor legit interest N", 202 config: purposeConfig{ 203 EnforceVendors: true, 204 }, 205 consentNoPubRestriction: NoConsents, 206 consentWithPubRestriction: NoConsentsWithP1P2P3V32RestrictionAllowAll, 207 wantConsentPurposeResult: false, 208 wantLIPurposeResult: false, 209 wantFlexPurposeResult: false, 210 }, 211 { 212 description: "enforce vendors on, vendor consent Y", 213 config: purposeConfig{ 214 EnforceVendors: true, 215 }, 216 consentNoPubRestriction: V32VendorConsent, 217 consentWithPubRestriction: V32VendorConsentWithP1P2P3V32RestrictionAllowAll, 218 wantConsentPurposeResult: true, 219 wantLIPurposeResult: false, 220 wantFlexPurposeResult: true, 221 }, 222 { 223 description: "enforce vendors on, vendor legit interest Y", 224 config: purposeConfig{ 225 EnforceVendors: true, 226 }, 227 consentNoPubRestriction: V32VendorLI, 228 consentWithPubRestriction: V32VendorLIWithP1P2P3V32RestrictionAllowAll, 229 wantConsentPurposeResult: false, 230 wantLIPurposeResult: true, 231 wantFlexPurposeResult: true, 232 }, 233 { 234 description: "enforce vendors on, vendor consent Y, enforce purpose off but overrides treats it as on", 235 config: purposeConfig{ 236 EnforceVendors: true, 237 }, 238 consentNoPubRestriction: V32VendorConsent, 239 consentWithPubRestriction: V32VendorConsentWithP1P2P3V32RestrictionAllowAll, 240 overrides: Overrides{enforcePurpose: true}, 241 wantConsentPurposeResult: false, 242 wantLIPurposeResult: false, 243 wantFlexPurposeResult: false, 244 }, 245 { 246 description: "enforce vendors on, purpose consent Y, vendor consent Y, enforce purpose off but overrides treats it as on", 247 config: purposeConfig{ 248 EnforceVendors: true, 249 }, 250 consentNoPubRestriction: P1P2P3PurposeConsentAndV32VendorConsent, 251 consentWithPubRestriction: P1P2P3PurposeConsentAndV32VendorConsentWithP1P2P3V32RestrictionAllowAll, 252 overrides: Overrides{enforcePurpose: true}, 253 wantConsentPurposeResult: true, 254 wantLIPurposeResult: false, 255 wantFlexPurposeResult: true, 256 }, 257 { 258 description: "enforce purpose & vendors on, purpose consent Y, vendor consent N", 259 config: purposeConfig{ 260 EnforcePurpose: true, 261 EnforceVendors: true, 262 }, 263 consentNoPubRestriction: P1P2P3PurposeConsent, 264 consentWithPubRestriction: P1P2P3PurposeConsentWithP1P2P3V32RestrictionAllowAll, 265 wantConsentPurposeResult: false, 266 wantLIPurposeResult: false, 267 wantFlexPurposeResult: false, 268 }, 269 { 270 description: "enforce purpose & vendors on, purpose consent N, vendor consent Y", 271 config: purposeConfig{ 272 EnforcePurpose: true, 273 EnforceVendors: true, 274 }, 275 consentNoPubRestriction: V32VendorConsent, 276 consentWithPubRestriction: V32VendorConsentWithP1P2P3V32RestrictionAllowAll, 277 wantConsentPurposeResult: false, 278 wantLIPurposeResult: false, 279 wantFlexPurposeResult: false, 280 }, 281 { 282 description: "enforce purpose & vendors on, purpose consent Y, vendor consent Y", 283 config: purposeConfig{ 284 EnforcePurpose: true, 285 EnforceVendors: true, 286 }, 287 consentNoPubRestriction: P1P2P3PurposeConsentAndV32VendorConsent, 288 consentWithPubRestriction: P1P2P3PurposeConsentAndV32VendorConsentWithP1P2P3V32RestrictionAllowAll, 289 wantConsentPurposeResult: true, 290 wantLIPurposeResult: false, 291 wantFlexPurposeResult: true, 292 }, 293 { 294 description: "enforce purpose & vendors on, legit interest Y, vendor legit interest N", 295 config: purposeConfig{ 296 EnforcePurpose: true, 297 EnforceVendors: true, 298 }, 299 consentNoPubRestriction: P1P2P3PurposeLI, 300 consentWithPubRestriction: P1P2P3PurposeLIWithP1P2P3V32RestrictionAllowAll, 301 wantConsentPurposeResult: false, 302 wantLIPurposeResult: false, 303 wantFlexPurposeResult: false, 304 }, 305 { 306 description: "enforce purpose & vendors on, legit interest N, vendor legit interest Y", 307 config: purposeConfig{ 308 EnforcePurpose: true, 309 EnforceVendors: true, 310 }, 311 consentNoPubRestriction: V32VendorLI, 312 consentWithPubRestriction: V32VendorLIWithP1P2P3V32RestrictionAllowAll, 313 wantConsentPurposeResult: false, 314 wantLIPurposeResult: false, 315 wantFlexPurposeResult: false, 316 }, 317 { 318 description: "enforce purpose & vendors on, legit interest Y, vendor legit interest Y", 319 config: purposeConfig{ 320 EnforcePurpose: true, 321 EnforceVendors: true, 322 }, 323 consentNoPubRestriction: P1P2P3PurposeLIAndV32VendorLI, 324 consentWithPubRestriction: P1P2P3PurposeLIAndV32VendorLIWithP1P2P3V32RestrictionAllowAll, 325 wantConsentPurposeResult: false, 326 wantLIPurposeResult: true, 327 wantFlexPurposeResult: true, 328 }, 329 { 330 description: "enforce purpose & vendors on, bidder is a vendor exception", 331 config: purposeConfig{ 332 EnforcePurpose: true, 333 EnforceVendors: true, 334 VendorExceptionMap: map[string]struct{}{appnexus: {}}, 335 }, 336 consentNoPubRestriction: NoConsents, 337 consentWithPubRestriction: NoConsentsWithP1P2P3V32RestrictionAllowAll, 338 wantConsentPurposeResult: true, 339 wantLIPurposeResult: true, 340 wantFlexPurposeResult: true, 341 }, 342 { 343 description: "enforce purpose & vendors on, bidder is a vendor exception but overrides disallow them", 344 config: purposeConfig{ 345 EnforcePurpose: true, 346 EnforceVendors: true, 347 VendorExceptionMap: map[string]struct{}{appnexus: {}}, 348 }, 349 consentNoPubRestriction: NoConsents, 350 consentWithPubRestriction: NoConsentsWithP1P2P3V32RestrictionAllowAll, 351 overrides: Overrides{blockVendorExceptions: true}, 352 wantConsentPurposeResult: false, 353 wantLIPurposeResult: false, 354 wantFlexPurposeResult: false, 355 }, 356 } 357 358 for _, tt := range tests { 359 consents := [2]string{tt.consentNoPubRestriction, tt.consentWithPubRestriction} 360 361 for i := 0; i < len(consents); i++ { 362 consent := consents[i] 363 364 // convert consent string to TCF2 object 365 parsedConsent, err := vendorconsent.ParseString(consent) 366 if err != nil { 367 t.Fatalf("Failed to parse consent %s: %s\n", consent, tt.description) 368 } 369 consentMeta, ok := parsedConsent.(tcf2.ConsentMetadata) 370 if !ok { 371 t.Fatalf("Failed to convert consent %s: %s\n", consent, tt.description) 372 } 373 374 vendor := getVendorList(t).Vendor(appnexusID) 375 vendorInfo := VendorInfo{vendorID: appnexusID, vendor: vendor} 376 enforcer := FullEnforcement{cfg: tt.config} 377 378 enforcer.cfg.PurposeID = consentconstants.Purpose(1) 379 consentPurposeResult := enforcer.LegalBasis(vendorInfo, appnexus, consentMeta, tt.overrides) 380 assert.Equal(t, tt.wantConsentPurposeResult, consentPurposeResult, tt.description+" -- GVL consent purpose -- consent string %d of %d", i+1, len(consents)) 381 382 enforcer.cfg.PurposeID = consentconstants.Purpose(2) 383 LIPurposeresult := enforcer.LegalBasis(vendorInfo, appnexus, consentMeta, tt.overrides) 384 assert.Equal(t, tt.wantLIPurposeResult, LIPurposeresult, tt.description+" -- GVL LI purpose -- consent string %d of %d", i+1, len(consents)) 385 386 enforcer.cfg.PurposeID = consentconstants.Purpose(3) 387 flexPurposeResult := enforcer.LegalBasis(vendorInfo, appnexus, consentMeta, tt.overrides) 388 assert.Equal(t, tt.wantFlexPurposeResult, flexPurposeResult, tt.description+" -- GVL flex purpose -- consent string %d of %d", i+1, len(consents)) 389 } 390 } 391 } 392 393 func TestLegalBasisWithPubRestrictionRequireConsent(t *testing.T) { 394 var ( 395 appnexus = string(openrtb_ext.BidderAppnexus) 396 appnexusID = uint16(32) 397 ) 398 399 NoConsentsWithP1P2P3V32RestrictionRequireConsent := "CPfFkMAPfFkMAAAAAAENCgCAAAAAAAAAAAAAAQAAAAAAAIAAAAAAAGCgAgAgCQAQAQBoAIAIAAAA" 400 P1P2P3PurposeConsentWithP1P2P3V32RestrictionRequireConsent := "CPfFkMAPfFkMAAAAAAENCgCAAOAAAAAAAAAAAQAAAAAAAIAAAAAAAGCgAgAgCQAQAQBoAIAIAAAA" 401 P1P2P3PurposeLIWithP1P2P3V32RestrictionRequireConsent := "CPfFkMAPfFkMAAAAAAENCgCAAAAAAOAAAAAAAQAAAAAAAIAAAAAAAGCgAgAgCQAQAQBoAIAIAAAA" 402 V32VendorConsentWithP1P2P3V32RestrictionRequireConsent := "CPfFkMAPfFkMAAAAAAENCgCAAAAAAAAAAAAAAQAAAAAEAIAAAAAAAGCgAgAgCQAQAQBoAIAIAAAA" 403 V32VendorLIWithP1P2P3V32RestrictionRequireConsent := "CPfFkMAPfFkMAAAAAAENCgCAAAAAAAAAAAAAAQAAAAAAAIAAAAACAGCgAgAgCQAQAQBoAIAIAAAA" 404 P1P2P3PurposeConsentAndV32VendorConsentWithP1P2P3V32RestrictionRequireConsent := "CPfFkMAPfFkMAAAAAAENCgCAAOAAAAAAAAAAAQAAAAAEAIAAAAAAAGCgAgAgCQAQAQBoAIAIAAAA" 405 P1P2P3PurposeLIAndV32VendorLIWithP1P2P3V32RestrictionRequireConsent := "CPfFkMAPfFkMAAAAAAENCgCAAAAAAOAAAAAAAQAAAAAAAIAAAAACAGCgAgAgCQAQAQBoAIAIAAAA" 406 407 tests := []struct { 408 description string 409 config purposeConfig 410 consent string 411 overrides Overrides 412 wantConsentPurposeResult bool 413 wantLIPurposeResult bool 414 wantFlexPurposeResult bool 415 }{ 416 { 417 description: "enforce purpose & vendors off", 418 config: purposeConfig{ 419 EnforcePurpose: false, 420 EnforceVendors: false, 421 }, 422 consent: NoConsentsWithP1P2P3V32RestrictionRequireConsent, 423 wantConsentPurposeResult: true, 424 wantLIPurposeResult: true, 425 wantFlexPurposeResult: true, 426 }, 427 { 428 description: "enforce purpose on, purpose consent N, legit interest N", 429 config: purposeConfig{ 430 EnforcePurpose: true, 431 }, 432 consent: NoConsentsWithP1P2P3V32RestrictionRequireConsent, 433 wantConsentPurposeResult: false, 434 wantLIPurposeResult: false, 435 wantFlexPurposeResult: false, 436 }, 437 { 438 description: "enforce purpose on, purpose consent Y", 439 config: purposeConfig{ 440 EnforcePurpose: true, 441 }, 442 consent: P1P2P3PurposeConsentWithP1P2P3V32RestrictionRequireConsent, 443 wantConsentPurposeResult: true, 444 wantLIPurposeResult: false, 445 wantFlexPurposeResult: true, 446 }, 447 { 448 description: "enforce purpose on, legit interest Y", 449 config: purposeConfig{ 450 EnforcePurpose: true, 451 }, 452 consent: P1P2P3PurposeLIWithP1P2P3V32RestrictionRequireConsent, 453 wantConsentPurposeResult: false, 454 wantLIPurposeResult: false, 455 wantFlexPurposeResult: false, 456 }, 457 { 458 description: "enforce purpose on, purpose consent Y, enforce vendors off but overrides treats it as on", 459 config: purposeConfig{ 460 EnforcePurpose: true, 461 }, 462 consent: P1P2P3PurposeConsentWithP1P2P3V32RestrictionRequireConsent, 463 overrides: Overrides{enforceVendors: true}, 464 wantConsentPurposeResult: false, 465 wantLIPurposeResult: false, 466 wantFlexPurposeResult: false, 467 }, 468 { 469 description: "enforce purpose on, purpose consent Y, vendor consent Y, enforce vendors off but overrides treats it as on", 470 config: purposeConfig{ 471 EnforcePurpose: true, 472 }, 473 consent: P1P2P3PurposeConsentAndV32VendorConsentWithP1P2P3V32RestrictionRequireConsent, 474 overrides: Overrides{enforceVendors: true}, 475 wantConsentPurposeResult: true, 476 wantLIPurposeResult: false, 477 wantFlexPurposeResult: true, 478 }, 479 { 480 description: "enforce vendors on, vendor consent N, vendor legit interest N", 481 config: purposeConfig{ 482 EnforceVendors: true, 483 }, 484 consent: NoConsentsWithP1P2P3V32RestrictionRequireConsent, 485 wantConsentPurposeResult: false, 486 wantLIPurposeResult: false, 487 wantFlexPurposeResult: false, 488 }, 489 { 490 description: "enforce vendors on, vendor consent Y", 491 config: purposeConfig{ 492 EnforceVendors: true, 493 }, 494 consent: V32VendorConsentWithP1P2P3V32RestrictionRequireConsent, 495 wantConsentPurposeResult: true, 496 wantLIPurposeResult: false, 497 wantFlexPurposeResult: true, 498 }, 499 { 500 description: "enforce vendors on, vendor legit interest Y", 501 config: purposeConfig{ 502 EnforceVendors: true, 503 }, 504 consent: V32VendorLIWithP1P2P3V32RestrictionRequireConsent, 505 wantConsentPurposeResult: false, 506 wantLIPurposeResult: false, 507 wantFlexPurposeResult: false, 508 }, 509 { 510 description: "enforce vendors on, vendor consent Y, enforce purpose off but overrides treats it as on", 511 config: purposeConfig{ 512 EnforceVendors: true, 513 }, 514 consent: V32VendorConsentWithP1P2P3V32RestrictionRequireConsent, 515 overrides: Overrides{enforcePurpose: true}, 516 wantConsentPurposeResult: false, 517 wantLIPurposeResult: false, 518 wantFlexPurposeResult: false, 519 }, 520 { 521 description: "enforce vendors on, purpose consent Y, vendor consent Y, enforce purpose off but overrides treats it as on", 522 config: purposeConfig{ 523 EnforceVendors: true, 524 }, 525 consent: P1P2P3PurposeConsentAndV32VendorConsentWithP1P2P3V32RestrictionRequireConsent, 526 overrides: Overrides{enforcePurpose: true}, 527 wantConsentPurposeResult: true, 528 wantLIPurposeResult: false, 529 wantFlexPurposeResult: true, 530 }, 531 { 532 description: "enforce purpose & vendors on, purpose consent Y, vendor consent N", 533 config: purposeConfig{ 534 EnforcePurpose: true, 535 EnforceVendors: true, 536 }, 537 consent: P1P2P3PurposeConsentWithP1P2P3V32RestrictionRequireConsent, 538 wantConsentPurposeResult: false, 539 wantLIPurposeResult: false, 540 wantFlexPurposeResult: false, 541 }, 542 { 543 description: "enforce purpose & vendors on, purpose consent N, vendor consent Y", 544 config: purposeConfig{ 545 EnforcePurpose: true, 546 EnforceVendors: true, 547 }, 548 consent: V32VendorConsentWithP1P2P3V32RestrictionRequireConsent, 549 wantConsentPurposeResult: false, 550 wantLIPurposeResult: false, 551 wantFlexPurposeResult: false, 552 }, 553 { 554 description: "enforce purpose & vendors on, purpose consent Y, vendor consent Y", 555 config: purposeConfig{ 556 EnforcePurpose: true, 557 EnforceVendors: true, 558 }, 559 consent: P1P2P3PurposeConsentAndV32VendorConsentWithP1P2P3V32RestrictionRequireConsent, 560 wantConsentPurposeResult: true, 561 wantLIPurposeResult: false, 562 wantFlexPurposeResult: true, 563 }, 564 { 565 description: "enforce purpose & vendors on, legit interest Y, vendor legit interest N", 566 config: purposeConfig{ 567 EnforcePurpose: true, 568 EnforceVendors: true, 569 }, 570 consent: P1P2P3PurposeLIWithP1P2P3V32RestrictionRequireConsent, 571 wantConsentPurposeResult: false, 572 wantLIPurposeResult: false, 573 wantFlexPurposeResult: false, 574 }, 575 { 576 description: "enforce purpose & vendors on, legit interest N, vendor legit interest Y", 577 config: purposeConfig{ 578 EnforcePurpose: true, 579 EnforceVendors: true, 580 }, 581 consent: V32VendorLIWithP1P2P3V32RestrictionRequireConsent, 582 wantConsentPurposeResult: false, 583 wantLIPurposeResult: false, 584 wantFlexPurposeResult: false, 585 }, 586 { 587 description: "enforce purpose & vendors on, legit interest Y, vendor legit interest Y", 588 config: purposeConfig{ 589 EnforcePurpose: true, 590 EnforceVendors: true, 591 }, 592 consent: P1P2P3PurposeLIAndV32VendorLIWithP1P2P3V32RestrictionRequireConsent, 593 wantConsentPurposeResult: false, 594 wantLIPurposeResult: false, 595 wantFlexPurposeResult: false, 596 }, 597 { 598 description: "enforce purpose & vendors on, bidder is a vendor exception", 599 config: purposeConfig{ 600 EnforcePurpose: true, 601 EnforceVendors: true, 602 VendorExceptionMap: map[string]struct{}{appnexus: {}}, 603 }, 604 consent: NoConsentsWithP1P2P3V32RestrictionRequireConsent, 605 wantConsentPurposeResult: true, 606 wantLIPurposeResult: true, 607 wantFlexPurposeResult: true, 608 }, 609 { 610 description: "enforce purpose & vendors on, bidder is a vendor exception but overrides disallow them", 611 config: purposeConfig{ 612 EnforcePurpose: true, 613 EnforceVendors: true, 614 VendorExceptionMap: map[string]struct{}{appnexus: {}}, 615 }, 616 consent: NoConsentsWithP1P2P3V32RestrictionRequireConsent, 617 overrides: Overrides{blockVendorExceptions: true}, 618 wantConsentPurposeResult: false, 619 wantLIPurposeResult: false, 620 wantFlexPurposeResult: false, 621 }, 622 } 623 624 for _, tt := range tests { 625 // convert consent string to TCF2 object 626 parsedConsent, err := vendorconsent.ParseString(tt.consent) 627 if err != nil { 628 t.Fatalf("Failed to parse consent %s: %s\n", tt.consent, tt.description) 629 } 630 consentMeta, ok := parsedConsent.(tcf2.ConsentMetadata) 631 if !ok { 632 t.Fatalf("Failed to convert consent %s: %s\n", tt.consent, tt.description) 633 } 634 635 vendor := getVendorList(t).Vendor(appnexusID) 636 vendorInfo := VendorInfo{vendorID: appnexusID, vendor: vendor} 637 enforcer := FullEnforcement{cfg: tt.config} 638 639 enforcer.cfg.PurposeID = consentconstants.Purpose(1) 640 consentPurposeResult := enforcer.LegalBasis(vendorInfo, appnexus, consentMeta, tt.overrides) 641 assert.Equal(t, tt.wantConsentPurposeResult, consentPurposeResult, tt.description+" -- GVL consent purpose") 642 643 enforcer.cfg.PurposeID = consentconstants.Purpose(2) 644 LIPurposeresult := enforcer.LegalBasis(vendorInfo, appnexus, consentMeta, tt.overrides) 645 assert.Equal(t, tt.wantLIPurposeResult, LIPurposeresult, tt.description+" -- GVL LI purpose") 646 647 enforcer.cfg.PurposeID = consentconstants.Purpose(3) 648 flexPurposeResult := enforcer.LegalBasis(vendorInfo, appnexus, consentMeta, tt.overrides) 649 assert.Equal(t, tt.wantFlexPurposeResult, flexPurposeResult, tt.description+" -- GVL flex purpose") 650 } 651 } 652 653 func TestLegalBasisWithPubRestrictionRequireLI(t *testing.T) { 654 var ( 655 appnexus = string(openrtb_ext.BidderAppnexus) 656 appnexusID = uint16(32) 657 ) 658 659 NoConsentsWithP1P2P3V32RestrictionRequireLI := "CPfFkMAPfFkMAAAAAAENCgCAAAAAAAAAAAAAAQAAAAAAAIAAAAAAAGDAAgAgCgAQAQBwAIAIAAAA" 660 P1P2P3PurposeConsentWithP1P2P3V32RestrictionRequireLI := "CPfFkMAPfFkMAAAAAAENCgCAAOAAAAAAAAAAAQAAAAAAAIAAAAAAAGDAAgAgCgAQAQBwAIAIAAAA" 661 P1P2P3PurposeLIWithP1P2P3V32RestrictionRequireLI := "CPfFkMAPfFkMAAAAAAENCgCAAAAAAOAAAAAAAQAAAAAAAIAAAAAAAGDAAgAgCgAQAQBwAIAIAAAA" 662 V32VendorConsentWithP1P2P3V32RestrictionRequireLI := "CPfFkMAPfFkMAAAAAAENCgCAAAAAAAAAAAAAAQAAAAAEAIAAAAAAAGDAAgAgCgAQAQBwAIAIAAAA" 663 V32VendorLIWithP1P2P3V32RestrictionRequireLI := "CPfFkMAPfFkMAAAAAAENCgCAAAAAAAAAAAAAAQAAAAAAAIAAAAACAGDAAgAgCgAQAQBwAIAIAAAA" 664 P1P2P3PurposeConsentAndV32VendorConsentWithP1P2P3V32RestrictionRequireLI := "CPfFkMAPfFkMAAAAAAENCgCAAOAAAAAAAAAAAQAAAAAEAIAAAAAAAGDAAgAgCgAQAQBwAIAIAAAA" 665 P1P2P3PurposeLIAndV32VendorLIWithP1P2P3V32RestrictionRequireLI := "CPfFkMAPfFkMAAAAAAENCgCAAAAAAOAAAAAAAQAAAAAAAIAAAAACAGDAAgAgCgAQAQBwAIAIAAAA" 666 667 tests := []struct { 668 description string 669 config purposeConfig 670 consent string 671 overrides Overrides 672 wantConsentPurposeResult bool 673 wantLIPurposeResult bool 674 wantFlexPurposeResult bool 675 }{ 676 { 677 description: "enforce purpose & vendors off", 678 config: purposeConfig{ 679 EnforcePurpose: false, 680 EnforceVendors: false, 681 }, 682 consent: NoConsentsWithP1P2P3V32RestrictionRequireLI, 683 wantConsentPurposeResult: true, 684 wantLIPurposeResult: true, 685 wantFlexPurposeResult: true, 686 }, 687 { 688 description: "enforce purpose on, purpose consent N, legit interest N", 689 config: purposeConfig{ 690 EnforcePurpose: true, 691 }, 692 consent: NoConsentsWithP1P2P3V32RestrictionRequireLI, 693 wantConsentPurposeResult: false, 694 wantLIPurposeResult: false, 695 wantFlexPurposeResult: false, 696 }, 697 { 698 description: "enforce purpose on, purpose consent Y", 699 config: purposeConfig{ 700 EnforcePurpose: true, 701 }, 702 consent: P1P2P3PurposeConsentWithP1P2P3V32RestrictionRequireLI, 703 wantConsentPurposeResult: false, 704 wantLIPurposeResult: false, 705 wantFlexPurposeResult: false, 706 }, 707 { 708 description: "enforce purpose on, legit interest Y", 709 config: purposeConfig{ 710 EnforcePurpose: true, 711 }, 712 consent: P1P2P3PurposeLIWithP1P2P3V32RestrictionRequireLI, 713 wantConsentPurposeResult: false, 714 wantLIPurposeResult: true, 715 wantFlexPurposeResult: true, 716 }, 717 { 718 description: "enforce purpose on, vendor legit interest Y, enforce vendors off but overrides treats it as on", 719 config: purposeConfig{ 720 EnforcePurpose: true, 721 }, 722 consent: P1P2P3PurposeLIWithP1P2P3V32RestrictionRequireLI, 723 overrides: Overrides{enforceVendors: true}, 724 wantConsentPurposeResult: false, 725 wantLIPurposeResult: false, 726 wantFlexPurposeResult: false, 727 }, 728 { 729 description: "enforce purpose on, vendor legit interest Y, vendor consent Y, enforce vendors off but overrides treats it as on", 730 config: purposeConfig{ 731 EnforcePurpose: true, 732 }, 733 consent: P1P2P3PurposeLIAndV32VendorLIWithP1P2P3V32RestrictionRequireLI, 734 overrides: Overrides{enforceVendors: true}, 735 wantConsentPurposeResult: false, 736 wantLIPurposeResult: true, 737 wantFlexPurposeResult: true, 738 }, 739 { 740 description: "enforce vendors on, vendor consent N, vendor legit interest N", 741 config: purposeConfig{ 742 EnforceVendors: true, 743 }, 744 consent: NoConsentsWithP1P2P3V32RestrictionRequireLI, 745 wantConsentPurposeResult: false, 746 wantLIPurposeResult: false, 747 wantFlexPurposeResult: false, 748 }, 749 { 750 description: "enforce vendors on, vendor consent Y", 751 config: purposeConfig{ 752 EnforceVendors: true, 753 }, 754 consent: V32VendorConsentWithP1P2P3V32RestrictionRequireLI, 755 wantConsentPurposeResult: false, 756 wantLIPurposeResult: false, 757 wantFlexPurposeResult: false, 758 }, 759 { 760 description: "enforce vendors on, vendor legit interest Y", 761 config: purposeConfig{ 762 EnforceVendors: true, 763 }, 764 consent: V32VendorLIWithP1P2P3V32RestrictionRequireLI, 765 wantConsentPurposeResult: false, 766 wantLIPurposeResult: true, 767 wantFlexPurposeResult: true, 768 }, 769 { 770 description: "enforce vendors on, vendor legit interest Y, enforce purpose off but overrides treats it as on", 771 config: purposeConfig{ 772 EnforceVendors: true, 773 }, 774 consent: V32VendorLIWithP1P2P3V32RestrictionRequireLI, 775 overrides: Overrides{enforcePurpose: true}, 776 wantConsentPurposeResult: false, 777 wantLIPurposeResult: false, 778 wantFlexPurposeResult: false, 779 }, 780 { 781 description: "enforce vendors on, vendor legit interest Y, vendor consent Y, enforce purpose off but overrides treats it as on", 782 config: purposeConfig{ 783 EnforceVendors: true, 784 }, 785 consent: P1P2P3PurposeLIAndV32VendorLIWithP1P2P3V32RestrictionRequireLI, 786 overrides: Overrides{enforcePurpose: true}, 787 wantConsentPurposeResult: false, 788 wantLIPurposeResult: true, 789 wantFlexPurposeResult: true, 790 }, 791 { 792 description: "enforce purpose & vendors on, purpose consent Y, vendor consent N", 793 config: purposeConfig{ 794 EnforcePurpose: true, 795 EnforceVendors: true, 796 }, 797 consent: P1P2P3PurposeConsentWithP1P2P3V32RestrictionRequireLI, 798 wantConsentPurposeResult: false, 799 wantLIPurposeResult: false, 800 wantFlexPurposeResult: false, 801 }, 802 { 803 description: "enforce purpose & vendors on, purpose consent N, vendor consent Y", 804 config: purposeConfig{ 805 EnforcePurpose: true, 806 EnforceVendors: true, 807 }, 808 consent: V32VendorConsentWithP1P2P3V32RestrictionRequireLI, 809 wantConsentPurposeResult: false, 810 wantLIPurposeResult: false, 811 wantFlexPurposeResult: false, 812 }, 813 { 814 description: "enforce purpose & vendors on, purpose consent Y, vendor consent Y", 815 config: purposeConfig{ 816 EnforcePurpose: true, 817 EnforceVendors: true, 818 }, 819 consent: P1P2P3PurposeConsentAndV32VendorConsentWithP1P2P3V32RestrictionRequireLI, 820 wantConsentPurposeResult: false, 821 wantLIPurposeResult: false, 822 wantFlexPurposeResult: false, 823 }, 824 { 825 description: "enforce purpose & vendors on, legit interest Y, vendor legit interest N", 826 config: purposeConfig{ 827 EnforcePurpose: true, 828 EnforceVendors: true, 829 }, 830 consent: P1P2P3PurposeLIWithP1P2P3V32RestrictionRequireLI, 831 wantConsentPurposeResult: false, 832 wantLIPurposeResult: false, 833 wantFlexPurposeResult: false, 834 }, 835 { 836 description: "enforce purpose & vendors on, legit interest N, vendor legit interest Y", 837 config: purposeConfig{ 838 EnforcePurpose: true, 839 EnforceVendors: true, 840 }, 841 consent: V32VendorLIWithP1P2P3V32RestrictionRequireLI, 842 wantConsentPurposeResult: false, 843 wantLIPurposeResult: false, 844 wantFlexPurposeResult: false, 845 }, 846 { 847 description: "enforce purpose & vendors on, legit interest Y, vendor legit interest Y", 848 config: purposeConfig{ 849 EnforcePurpose: true, 850 EnforceVendors: true, 851 }, 852 consent: P1P2P3PurposeLIAndV32VendorLIWithP1P2P3V32RestrictionRequireLI, 853 wantConsentPurposeResult: false, 854 wantLIPurposeResult: true, 855 wantFlexPurposeResult: true, 856 }, 857 { 858 description: "enforce purpose & vendors on, bidder is a vendor exception", 859 config: purposeConfig{ 860 EnforcePurpose: true, 861 EnforceVendors: true, 862 VendorExceptionMap: map[string]struct{}{appnexus: {}}, 863 }, 864 consent: NoConsentsWithP1P2P3V32RestrictionRequireLI, 865 wantConsentPurposeResult: true, 866 wantLIPurposeResult: true, 867 wantFlexPurposeResult: true, 868 }, 869 { 870 description: "enforce purpose & vendors on, bidder is a vendor exception but overrides disallow them", 871 config: purposeConfig{ 872 EnforcePurpose: true, 873 EnforceVendors: true, 874 VendorExceptionMap: map[string]struct{}{appnexus: {}}, 875 }, 876 consent: NoConsentsWithP1P2P3V32RestrictionRequireLI, 877 overrides: Overrides{blockVendorExceptions: true}, 878 wantConsentPurposeResult: false, 879 wantLIPurposeResult: false, 880 wantFlexPurposeResult: false, 881 }, 882 } 883 884 for _, tt := range tests { 885 // convert consent string to TCF2 object 886 parsedConsent, err := vendorconsent.ParseString(tt.consent) 887 if err != nil { 888 t.Fatalf("Failed to parse consent %s: %s\n", tt.consent, tt.description) 889 } 890 consentMeta, ok := parsedConsent.(tcf2.ConsentMetadata) 891 if !ok { 892 t.Fatalf("Failed to convert consent %s: %s\n", tt.consent, tt.description) 893 } 894 895 vendor := getVendorList(t).Vendor(appnexusID) 896 vendorInfo := VendorInfo{vendorID: appnexusID, vendor: vendor} 897 enforcer := FullEnforcement{cfg: tt.config} 898 899 enforcer.cfg.PurposeID = consentconstants.Purpose(1) 900 consentPurposeResult := enforcer.LegalBasis(vendorInfo, appnexus, consentMeta, tt.overrides) 901 assert.Equal(t, tt.wantConsentPurposeResult, consentPurposeResult, tt.description+" -- GVL consent purpose") 902 903 enforcer.cfg.PurposeID = consentconstants.Purpose(2) 904 LIPurposeresult := enforcer.LegalBasis(vendorInfo, appnexus, consentMeta, tt.overrides) 905 assert.Equal(t, tt.wantLIPurposeResult, LIPurposeresult, tt.description+" -- GVL LI purpose") 906 907 enforcer.cfg.PurposeID = consentconstants.Purpose(3) 908 flexPurposeResult := enforcer.LegalBasis(vendorInfo, appnexus, consentMeta, tt.overrides) 909 assert.Equal(t, tt.wantFlexPurposeResult, flexPurposeResult, tt.description+" -- GVL flex purpose") 910 } 911 } 912 913 func TestLegalBasisWithoutVendor(t *testing.T) { 914 appnexus := string(openrtb_ext.BidderAppnexus) 915 P1P2P3PurposeConsent := "CPfCRQAPfCRQAAAAAAENCgCAAOAAAAAAAAAAAAAAAAAA" 916 tests := []struct { 917 name string 918 config purposeConfig 919 wantResult bool 920 }{ 921 { 922 name: "enforce_purpose_&_vendors_off", 923 config: purposeConfig{ 924 EnforcePurpose: false, 925 EnforceVendors: false, 926 }, 927 wantResult: true, 928 }, 929 { 930 name: "enforce_purpose_on,_bidder_is_a_vendor_exception", 931 config: purposeConfig{ 932 EnforcePurpose: true, 933 EnforceVendors: false, 934 VendorExceptionMap: map[string]struct{}{appnexus: {}}, 935 }, 936 wantResult: true, 937 }, 938 { 939 name: "enforce_purpose_on", 940 config: purposeConfig{ 941 EnforcePurpose: true, 942 EnforceVendors: false, 943 }, 944 wantResult: false, 945 }, 946 } 947 948 for _, tt := range tests { 949 t.Run(tt.name, func(t *testing.T) { 950 // convert consent string to TCF2 object 951 parsedConsent, err := vendorconsent.ParseString(P1P2P3PurposeConsent) 952 if err != nil { 953 t.Fatalf("Failed to parse consent %s\n", P1P2P3PurposeConsent) 954 } 955 consentMeta, ok := parsedConsent.(tcf2.ConsentMetadata) 956 if !ok { 957 t.Fatalf("Failed to convert consent %s\n", P1P2P3PurposeConsent) 958 } 959 960 vendorInfo := VendorInfo{ 961 vendorID: 32, 962 vendor: nil, 963 } 964 965 enforcer := FullEnforcement{cfg: tt.config} 966 enforcer.cfg.PurposeID = consentconstants.Purpose(3) 967 968 result := enforcer.LegalBasis(vendorInfo, appnexus, consentMeta, Overrides{}) 969 assert.Equal(t, tt.wantResult, result) 970 }) 971 } 972 } 973 974 func getVendorList(t *testing.T) vendorlist.VendorList { 975 GVL := makeVendorList() 976 977 marshaledGVL, err := jsonutil.Marshal(GVL) 978 if err != nil { 979 t.Fatalf("Failed to marshal GVL") 980 } 981 982 parsedGVL, err := vendorlist2.ParseEagerly(marshaledGVL) 983 if err != nil { 984 t.Fatalf("Failed to parse vendor list data. %v", err) 985 } 986 return parsedGVL 987 } 988 989 func makeVendorList() vendorList { 990 return vendorList{ 991 VendorListVersion: 2, 992 Vendors: map[string]*vendor{ 993 "32": { 994 ID: 32, 995 Purposes: []int{1}, 996 LegIntPurposes: []int{2}, 997 FlexiblePurposes: []int{3}, 998 }, 999 }, 1000 } 1001 }