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