From 4adf6d6cfcd4c7ad3199d739b9f9588aa08ffafc Mon Sep 17 00:00:00 2001 From: markiian Date: Wed, 22 Jan 2025 16:00:08 +0200 Subject: [PATCH 1/3] Add func tests for scrubbed metrics --- .../tests/privacy/GdprAuctionSpec.groovy | 85 +++++++++++++++++++ .../tests/privacy/PrivacyBaseSpec.groovy | 5 +- 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy index 351875e5f90..c4209573085 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy @@ -960,4 +960,89 @@ class GdprAuctionSpec extends PrivacyBaseSpec { null | BULGARIA | null | null | [:] null | null | null | null | [:] } + + def "PBS auction should update buyeruid scrubbed metrics when user.buyeruid requested"() { + given: "Default bid requests with personal data" + def tcfConsent = new TcfConsent.Builder().build() + def bidRequest = bidRequestWithPersonalData.tap { + regs.gdpr = 1 + user.ext.consent = tcfConsent + ext.prebid.trace = VERBOSE + } + + and: "Save account config with requireConsent into DB" + def purposes = [(P2): new PurposeConfig(enforcePurpose: NO, enforceVendors: false)] + def accountGdprConfig = new AccountGdprConfig(purposes: purposes) + def account = getAccountWithGdpr(bidRequest.accountId, accountGdprConfig) + accountDao.save(account) + + and: "Flush metric" + flushMetrics(privacyPbsService) + + when: "PBS processes auction requests" + privacyPbsService.sendAuctionRequest(bidRequest) + + then: "Bidder request should mask user personal data" + def bidderRequest = bidder.getBidderRequest(bidRequest.id) + verifyAll(bidderRequest.user) { + !id + !buyeruid + !yob + !gender + !eids + !data + !geo + !ext + !eids + !ext?.eids + } + + and: "Metrics buyeruid scrubbed should be updated" + def metrics = privacyPbsService.sendCollectedMetricsRequest() + assert metrics["adapter.${GENERIC.value}.requests.buyeruid_scrubbed"] == 1 + assert metrics["account.${account.uuid}.adapter.${GENERIC.value}.requests.buyeruid_scrubbed"] == 1 + } + + def "PBS auction shouldn't update buyeruid scrubbed metrics when user.buyeruid not requested"() { + given: "Default bid requests with personal data" + def tcfConsent = new TcfConsent.Builder().build() + def bidRequest = bidRequestWithPersonalData.tap { + regs.gdpr = 1 + user.ext.consent = tcfConsent + user.buyeruid = null + ext.prebid.trace = VERBOSE + } + + and: "Save account config with requireConsent into DB" + def purposes = [(P2): new PurposeConfig(enforcePurpose: NO, enforceVendors: false)] + def accountGdprConfig = new AccountGdprConfig(purposes: purposes) + def account = getAccountWithGdpr(bidRequest.accountId, accountGdprConfig) + accountDao.save(account) + + and: "Flush metric" + flushMetrics(privacyPbsService) + + when: "PBS processes auction requests" + privacyPbsService.sendAuctionRequest(bidRequest) + + then: "Bidder request should mask user personal data" + def bidderRequest = bidder.getBidderRequest(bidRequest.id) + verifyAll(bidderRequest.user) { + !id + !buyeruid + !yob + !gender + !eids + !data + !geo + !ext + !eids + !ext?.eids + } + + and: "Metrics buyeruid scrubbed shouldn't be updated" + def metrics = privacyPbsService.sendCollectedMetricsRequest() + assert !metrics["adapter.${GENERIC.value}.requests.buyeruid_scrubbed"] + assert !metrics["account.${account.uuid}.adapter.${GENERIC.value}.requests.buyeruid_scrubbed"] + } } diff --git a/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy index d4cbf17e2dd..269cf100cdf 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy @@ -7,6 +7,7 @@ import org.prebid.server.functional.model.config.AccountCoopSyncConfig import org.prebid.server.functional.model.config.AccountDsaConfig import org.prebid.server.functional.model.config.AccountGdprConfig import org.prebid.server.functional.model.config.AccountGppConfig +import org.prebid.server.functional.model.config.AccountMetricsConfig import org.prebid.server.functional.model.config.AccountPrivacyConfig import org.prebid.server.functional.model.config.Purpose import org.prebid.server.functional.model.db.Account @@ -38,6 +39,7 @@ import spock.lang.Shared import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.bidder.BidderName.OPENX +import static org.prebid.server.functional.model.config.AccountMetricsVerbosityLevel.DETAILED import static org.prebid.server.functional.model.config.PurposeEnforcement.BASIC import static org.prebid.server.functional.model.config.PurposeEnforcement.FULL import static org.prebid.server.functional.model.config.PurposeEnforcement.NO @@ -263,7 +265,8 @@ abstract class PrivacyBaseSpec extends BaseSpec { } private static Account getAccountWithPrivacy(String accountId, AccountPrivacyConfig privacy) { - new Account(uuid: accountId, config: new AccountConfig(privacy: privacy)) + def metricsConfig = new AccountMetricsConfig(verbosityLevel: DETAILED) + new Account(uuid: accountId, config: new AccountConfig(privacy: privacy, metrics: metricsConfig)) } protected static Account getAccountWithAllowActivitiesAndPrivacyModule(String accountId, From 82ab26eccb134e1ef680e6c52712a4130b10c396 Mon Sep 17 00:00:00 2001 From: markiian Date: Thu, 23 Jan 2025 14:49:19 +0200 Subject: [PATCH 2/3] Update after review --- .../tests/privacy/GdprAuctionSpec.groovy | 80 ++++++++++++++++--- .../tests/privacy/PrivacyBaseSpec.groovy | 3 +- 2 files changed, 68 insertions(+), 15 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy index c4209573085..7302ad79aed 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/privacy/GdprAuctionSpec.groovy @@ -3,6 +3,8 @@ package org.prebid.server.functional.tests.privacy import org.mockserver.model.Delay import org.prebid.server.functional.model.ChannelType import org.prebid.server.functional.model.config.AccountGdprConfig +import org.prebid.server.functional.model.config.AccountMetricsConfig +import org.prebid.server.functional.model.config.AccountMetricsVerbosityLevel import org.prebid.server.functional.model.config.PurposeConfig import org.prebid.server.functional.model.config.PurposeEnforcement import org.prebid.server.functional.model.pricefloors.Country @@ -21,6 +23,8 @@ import java.time.Instant import static org.prebid.server.functional.model.ChannelType.PBJS import static org.prebid.server.functional.model.ChannelType.WEB import static org.prebid.server.functional.model.bidder.BidderName.GENERIC + +import static org.prebid.server.functional.model.config.AccountMetricsVerbosityLevel.DETAILED import static org.prebid.server.functional.model.config.Purpose.P1 import static org.prebid.server.functional.model.config.Purpose.P2 import static org.prebid.server.functional.model.config.Purpose.P4 @@ -961,19 +965,67 @@ class GdprAuctionSpec extends PrivacyBaseSpec { null | null | null | null | [:] } - def "PBS auction should update buyeruid scrubbed metrics when user.buyeruid requested"() { + def "PBS auction shouldn't update buyeruid scrubbed metrics when user.buyeruid not requested"() { given: "Default bid requests with personal data" - def tcfConsent = new TcfConsent.Builder().build() def bidRequest = bidRequestWithPersonalData.tap { regs.gdpr = 1 - user.ext.consent = tcfConsent + user.buyeruid = null + user.ext.consent = new TcfConsent.Builder().build() ext.prebid.trace = VERBOSE } and: "Save account config with requireConsent into DB" def purposes = [(P2): new PurposeConfig(enforcePurpose: NO, enforceVendors: false)] def accountGdprConfig = new AccountGdprConfig(purposes: purposes) - def account = getAccountWithGdpr(bidRequest.accountId, accountGdprConfig) + def account = getAccountWithGdpr(bidRequest.accountId, accountGdprConfig).tap { + config.metrics = new AccountMetricsConfig(verbosityLevel: verbosityLevel) + } + accountDao.save(account) + + and: "Flush metric" + flushMetrics(privacyPbsService) + + when: "PBS processes auction requests" + privacyPbsService.sendAuctionRequest(bidRequest) + + then: "Bidder request should mask user personal data" + def bidderRequest = bidder.getBidderRequest(bidRequest.id) + verifyAll(bidderRequest.user) { + !id + !buyeruid + !yob + !gender + !eids + !data + !geo + !ext + !eids + !ext?.eids + } + + and: "Metrics buyeruid scrubbed shouldn't be updated" + def metrics = privacyPbsService.sendCollectedMetricsRequest() + assert !metrics["adapter.${GENERIC.value}.requests.buyeruid_scrubbed"] + assert !metrics["account.${account.uuid}.adapter.${GENERIC.value}.requests.buyeruid_scrubbed"] + + where: + verbosityLevel << [DETAILED, AccountMetricsVerbosityLevel.BASIC] + } + + def "PBS auction should update buyeruid scrubbed general metrics when user.buyeruid requested and verbosityLevel BASIC"() { + given: "Default bid requests with personal data" + def bidRequest = bidRequestWithPersonalData.tap { + regs.gdpr = 1 + user.ext.consent = new TcfConsent.Builder().build() + ext.prebid.trace = VERBOSE + } + + and: "Save account config with requireConsent into DB" + def purposes = [(P2): new PurposeConfig(enforcePurpose: NO, enforceVendors: false)] + def accountGdprConfig = new AccountGdprConfig(purposes: purposes) + def account = getAccountWithGdpr(bidRequest.accountId, accountGdprConfig).tap { + config.metrics = new AccountMetricsConfig(verbosityLevel: AccountMetricsVerbosityLevel.BASIC) + } accountDao.save(account) and: "Flush metric" @@ -1000,23 +1052,25 @@ class GdprAuctionSpec extends PrivacyBaseSpec { and: "Metrics buyeruid scrubbed should be updated" def metrics = privacyPbsService.sendCollectedMetricsRequest() assert metrics["adapter.${GENERIC.value}.requests.buyeruid_scrubbed"] == 1 - assert metrics["account.${account.uuid}.adapter.${GENERIC.value}.requests.buyeruid_scrubbed"] == 1 + + and: "Account metric shouldn't be populated" + assert !metrics["account.${account.uuid}.adapter.${GENERIC.value}.requests.buyeruid_scrubbed"] } - def "PBS auction shouldn't update buyeruid scrubbed metrics when user.buyeruid not requested"() { + def "PBS auction should update buyeruid scrubbed general and account metrics when user.buyeruid requested and verbosityLevel DETAILED"() { given: "Default bid requests with personal data" - def tcfConsent = new TcfConsent.Builder().build() def bidRequest = bidRequestWithPersonalData.tap { regs.gdpr = 1 - user.ext.consent = tcfConsent - user.buyeruid = null + user.ext.consent = new TcfConsent.Builder().build() ext.prebid.trace = VERBOSE } and: "Save account config with requireConsent into DB" def purposes = [(P2): new PurposeConfig(enforcePurpose: NO, enforceVendors: false)] def accountGdprConfig = new AccountGdprConfig(purposes: purposes) - def account = getAccountWithGdpr(bidRequest.accountId, accountGdprConfig) + def account = getAccountWithGdpr(bidRequest.accountId, accountGdprConfig).tap { + config.metrics = new AccountMetricsConfig(verbosityLevel: DETAILED) + } accountDao.save(account) and: "Flush metric" @@ -1040,9 +1094,9 @@ class GdprAuctionSpec extends PrivacyBaseSpec { !ext?.eids } - and: "Metrics buyeruid scrubbed shouldn't be updated" + and: "Metrics buyeruid scrubbed should be updated" def metrics = privacyPbsService.sendCollectedMetricsRequest() - assert !metrics["adapter.${GENERIC.value}.requests.buyeruid_scrubbed"] - assert !metrics["account.${account.uuid}.adapter.${GENERIC.value}.requests.buyeruid_scrubbed"] + assert metrics["adapter.${GENERIC.value}.requests.buyeruid_scrubbed"] == 1 + assert metrics["account.${account.uuid}.adapter.${GENERIC.value}.requests.buyeruid_scrubbed"] == 1 } } diff --git a/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy index 269cf100cdf..b65632aa9b6 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy @@ -265,8 +265,7 @@ abstract class PrivacyBaseSpec extends BaseSpec { } private static Account getAccountWithPrivacy(String accountId, AccountPrivacyConfig privacy) { - def metricsConfig = new AccountMetricsConfig(verbosityLevel: DETAILED) - new Account(uuid: accountId, config: new AccountConfig(privacy: privacy, metrics: metricsConfig)) + new Account(uuid: accountId, config: new AccountConfig(privacy: privacy)) } protected static Account getAccountWithAllowActivitiesAndPrivacyModule(String accountId, From 35c0e59d74cb2f6b94f020803d4549a227cab6b8 Mon Sep 17 00:00:00 2001 From: markiian Date: Fri, 24 Jan 2025 16:04:38 +0200 Subject: [PATCH 3/3] Remove dead imports --- .../server/functional/tests/privacy/PrivacyBaseSpec.groovy | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy index b65632aa9b6..d4cbf17e2dd 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/privacy/PrivacyBaseSpec.groovy @@ -7,7 +7,6 @@ import org.prebid.server.functional.model.config.AccountCoopSyncConfig import org.prebid.server.functional.model.config.AccountDsaConfig import org.prebid.server.functional.model.config.AccountGdprConfig import org.prebid.server.functional.model.config.AccountGppConfig -import org.prebid.server.functional.model.config.AccountMetricsConfig import org.prebid.server.functional.model.config.AccountPrivacyConfig import org.prebid.server.functional.model.config.Purpose import org.prebid.server.functional.model.db.Account @@ -39,7 +38,6 @@ import spock.lang.Shared import static org.prebid.server.functional.model.bidder.BidderName.GENERIC import static org.prebid.server.functional.model.bidder.BidderName.OPENX -import static org.prebid.server.functional.model.config.AccountMetricsVerbosityLevel.DETAILED import static org.prebid.server.functional.model.config.PurposeEnforcement.BASIC import static org.prebid.server.functional.model.config.PurposeEnforcement.FULL import static org.prebid.server.functional.model.config.PurposeEnforcement.NO