Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,16 @@ import spock.lang.Shared
import java.time.Clock
import java.time.ZonedDateTime

import static org.prebid.server.functional.model.bidder.BidderName.ALIAS
import static org.prebid.server.functional.model.bidder.BidderName.ALIAS_CAMEL_CASE
import static org.prebid.server.functional.model.bidder.BidderName.APPNEXUS
import static org.prebid.server.functional.model.bidder.BidderName.EMPTY
import static org.prebid.server.functional.model.bidder.BidderName.GENERIC
import static org.prebid.server.functional.model.bidder.BidderName.GENERIC_CAMEL_CASE
import static org.prebid.server.functional.model.bidder.BidderName.OPENX
import static org.prebid.server.functional.model.bidder.BidderName.RUBICON
import static org.prebid.server.functional.model.bidder.BidderName.UNKNOWN
import static org.prebid.server.functional.model.bidder.BidderName.WILDCARD
import static org.prebid.server.functional.model.request.setuid.UidWithExpiry.defaultUidWithExpiry
import static org.prebid.server.functional.model.response.cookiesync.UserSyncInfo.Type.REDIRECT
import static org.prebid.server.functional.testcontainers.Dependencies.networkServiceContainer
Expand All @@ -37,11 +43,13 @@ class SetUidSpec extends BaseSpec {
"adapters.${APPNEXUS.value}.usersync.cookie-family-name" : APPNEXUS.value,
"adapters.${GENERIC.value}.usersync.${USER_SYNC_TYPE.value}.url" : USER_SYNC_URL,
"adapters.${GENERIC.value}.usersync.${USER_SYNC_TYPE.value}.support-cors": CORS_SUPPORT.toString()]
private static final Map<String, String> GENERIC_ALIAS_CONFIG = ["adapters.generic.aliases.alias.enabled" : "true",
"adapters.generic.aliases.alias.endpoint": "$networkServiceContainer.rootUri/auction".toString()]
private static final String TCF_ERROR_MESSAGE = "The gdpr_consent param prevents cookies from being saved"
private static final int UNAVAILABLE_FOR_LEGAL_REASONS_CODE = 451

@Shared
PrebidServerService prebidServerService = pbsServiceFactory.getService(PBS_CONFIG)
PrebidServerService prebidServerService = pbsServiceFactory.getService(PBS_CONFIG + GENERIC_ALIAS_CONFIG)

def "PBS should set uids cookie"() {
given: "Default SetuidRequest"
Expand Down Expand Up @@ -77,8 +85,8 @@ class SetUidSpec extends BaseSpec {

def "PBS setuid should return requested uids cookie when priority bidder not present in config"() {
given: "PBS config"
def prebidServerService = pbsServiceFactory.getService(PBS_CONFIG +
["cookie-sync.pri": null])
def pbsConfig = PBS_CONFIG + ["cookie-sync.pri": null]
def prebidServerService = pbsServiceFactory.getService(pbsConfig)

and: "Setuid request"
def request = SetuidRequest.defaultSetuidRequest.tap {
Expand All @@ -94,13 +102,16 @@ class SetUidSpec extends BaseSpec {
then: "Response should contain requested uids"
assert response.uidsCookie.tempUIDs[GENERIC]
assert response.uidsCookie.tempUIDs[RUBICON]

cleanup: "Stop and remove pbs container"
pbsServiceFactory.removeContainer(pbsConfig)
}

def "PBS setuid should return prioritized uids bidder when size is full"() {
given: "PBS config"
def genericBidder = GENERIC
def prebidServerService = pbsServiceFactory.getService(PBS_CONFIG +
["cookie-sync.pri": genericBidder.value])
def pbsConfig = PBS_CONFIG + ["cookie-sync.pri": genericBidder.value]
def prebidServerService = pbsServiceFactory.getService(pbsConfig)

and: "Setuid request"
def request = SetuidRequest.defaultSetuidRequest.tap {
Expand All @@ -119,12 +130,15 @@ class SetUidSpec extends BaseSpec {
then: "Response should contain uids cookies"
assert response.uidsCookie.tempUIDs[rubiconBidder]
assert response.uidsCookie.tempUIDs[genericBidder]

cleanup: "Stop and remove pbs container"
pbsServiceFactory.removeContainer(pbsConfig)
}

def "PBS setuid should remove earliest expiration bidder when size is full"() {
given: "PBS config"
def prebidServerService = pbsServiceFactory.getService(PBS_CONFIG +
["cookie-sync.pri": GENERIC.value])
def pbsConfig = PBS_CONFIG + ["cookie-sync.pri": GENERIC.value]
def prebidServerService = pbsServiceFactory.getService(pbsConfig)

and: "Setuid request"
def request = SetuidRequest.defaultSetuidRequest.tap {
Expand All @@ -147,12 +161,15 @@ class SetUidSpec extends BaseSpec {
then: "Response should contain uids cookies"
assert response.uidsCookie.tempUIDs[APPNEXUS]
assert response.uidsCookie.tempUIDs[GENERIC]

cleanup: "Stop and remove pbs container"
pbsServiceFactory.removeContainer(pbsConfig)
}

def "PBS setuid should ignore requested bidder and log metric when cookie's filled and requested bidder not in prioritize list"() {
given: "PBS config"
def prebidServerService = pbsServiceFactory.getService(PBS_CONFIG +
["cookie-sync.pri": APPNEXUS.value])
def pbsConfig = PBS_CONFIG + ["cookie-sync.pri": APPNEXUS.value]
def prebidServerService = pbsServiceFactory.getService(pbsConfig)

and: "Setuid request"
def bidderName = GENERIC
Expand All @@ -176,14 +193,17 @@ class SetUidSpec extends BaseSpec {
and: "Response should contain uids cookies"
assert response.uidsCookie.tempUIDs[APPNEXUS]
assert response.uidsCookie.tempUIDs[RUBICON]

cleanup: "Stop and remove pbs container"
pbsServiceFactory.removeContainer(pbsConfig)
}

def "PBS setuid should reject bidder when cookie's filled and requested bidder in pri and rejected by tcf"() {
given: "Setuid request"
def bidderName = RUBICON
def prebidServerService = pbsServiceFactory.getService(PBS_CONFIG
+ ["gdpr.host-vendor-id": RUBICON_VENDOR_ID.toString(),
"cookie-sync.pri" : bidderName.value])
def pbsConfig = PBS_CONFIG + ["gdpr.host-vendor-id": RUBICON_VENDOR_ID.toString(),
"cookie-sync.pri" : bidderName.value]
def prebidServerService = pbsServiceFactory.getService(pbsConfig)

def request = SetuidRequest.defaultSetuidRequest.tap {
it.bidder = bidderName
Expand All @@ -207,12 +227,15 @@ class SetUidSpec extends BaseSpec {
and: "usersync.FAMILY.tcf.blocked metric should be updated"
def metric = prebidServerService.sendCollectedMetricsRequest()
assert metric["usersync.${bidderName.value}.tcf.blocked"] == 1

cleanup: "Stop and remove pbs container"
pbsServiceFactory.removeContainer(pbsConfig)
}

def "PBS setuid should remove oldest uid and log metric when cookie's filled and oldest uid's not on the pri"() {
given: "PBS config"
def prebidServerService = pbsServiceFactory.getService(PBS_CONFIG +
["cookie-sync.pri": GENERIC.value])
def pbsConfig = PBS_CONFIG + ["cookie-sync.pri": GENERIC.value]
def prebidServerService = pbsServiceFactory.getService(pbsConfig)

and: "Flush metrics"
flushMetrics(prebidServerService)
Expand Down Expand Up @@ -241,12 +264,15 @@ class SetUidSpec extends BaseSpec {
then: "Response should contain uids cookies"
assert response.uidsCookie.tempUIDs[APPNEXUS]
assert response.uidsCookie.tempUIDs[GENERIC]

cleanup: "Stop and remove pbs container"
pbsServiceFactory.removeContainer(pbsConfig)
}

def "PBS SetUid should remove oldest bidder from uids cookie in favor of prioritized bidder"() {
given: "PBS config"
def prebidServerService = pbsServiceFactory.getService(PBS_CONFIG +
["cookie-sync.pri": "$OPENX.value, $GENERIC.value" as String])
def pbsConfig = PBS_CONFIG + ["cookie-sync.pri": "$OPENX.value, $GENERIC.value" as String]
def prebidServerService = pbsServiceFactory.getService(pbsConfig)

and: "Set uid request"
def request = SetuidRequest.defaultSetuidRequest.tap {
Expand Down Expand Up @@ -281,5 +307,26 @@ class SetUidSpec extends BaseSpec {

and: "usersync.FAMILY.sets metric should be updated"
assert metricsRequest["usersync.${OPENX.value}.sets"] == 1

cleanup: "Stop and remove pbs container"
pbsServiceFactory.removeContainer(pbsConfig)
}

def "PBS setuid should reject request when requested bidder mismatching with cookie-family-name"() {
given: "Default SetuidRequest"
def request = SetuidRequest.getDefaultSetuidRequest().tap {
it.bidder = bidderName
}

when: "PBS processes setuid request"
prebidServerService.sendSetUidRequest(request, UidsCookie.defaultUidsCookie)

then: "Request should fail with error"
def exception = thrown(PrebidServerException)
assert exception.statusCode == 400
assert exception.responseBody == 'Invalid request format: "bidder" query param is invalid'

where:
bidderName << [UNKNOWN, WILDCARD, GENERIC_CAMEL_CASE, ALIAS, ALIAS_CAMEL_CASE]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.prebid.server.util.ResourceUtil

import static org.prebid.server.functional.model.AccountStatus.ACTIVE
import static org.prebid.server.functional.model.bidder.BidderName.GENERIC
import static org.prebid.server.functional.model.bidder.BidderName.GENER_X
import static org.prebid.server.functional.model.config.Purpose.P1
import static org.prebid.server.functional.model.config.PurposeEnforcement.FULL
import static org.prebid.server.functional.model.config.PurposeEnforcement.NO
Expand Down Expand Up @@ -53,7 +54,7 @@ class GdprSetUidSpec extends PrivacyBaseSpec {
.build()
}

and: "Default uids cookie with rubicon bidder"
and: "Default uids cookie with gener_x bidder"
def uidsCookie = UidsCookie.defaultUidsCookie.tap {
it.tempUIDs = [(GENERIC): defaultUidWithExpiry]
}
Expand All @@ -75,6 +76,90 @@ class GdprSetUidSpec extends PrivacyBaseSpec {
ResourceUtil.readByteArrayFromClassPath("org/prebid/server/functional/tracking-pixel.png")
}

def "PBS setuid shouldn't failed with tcf when bidder name and cookie-family-name mismatching"() {
given: "PBS with different cookie-family-name"
def pbsConfig = VENDOR_GENERIC_PBS_CONFIG +
["adapters.${GENERIC.value}.usersync.cookie-family-name": GENER_X.value]
def prebidServerService = pbsServiceFactory.getService(pbsConfig)

and: "Setuid request with account"
def setuidRequest = SetuidRequest.defaultSetuidRequest.tap {
it.account = PBSUtils.randomNumber.toString()
it.uid = UUID.randomUUID().toString()
it.bidder = GENER_X
it.gdpr = "1"
it.gdprConsent = new TcfConsent.Builder()
.setPurposesLITransparency(DEVICE_ACCESS)
.setVendorLegitimateInterest([GENERIC_VENDOR_ID])
.build()
}

and: "Default uids cookie with gener_x bidder"
def uidsCookie = UidsCookie.defaultUidsCookie.tap {
it.tempUIDs = [(GENER_X): defaultUidWithExpiry]
}

and: "Save account config with purpose into DB"
def accountConfig = new AccountConfig(
auction: new AccountAuctionConfig(debugAllow: true),
privacy: new AccountPrivacyConfig(gdpr: new AccountGdprConfig(purposes: [(P1): new PurposeConfig(enforcePurpose: NO)], enabled: true)))
def account = new Account(status: ACTIVE, uuid: setuidRequest.account, config: accountConfig)
accountDao.save(account)

when: "PBS processes setuid request"
def response = prebidServerService.sendSetUidRequest(setuidRequest, uidsCookie)

then: "Response should contain tempUids cookie and headers"
assert response.headers.size() == 7
assert response.uidsCookie.tempUIDs[GENER_X].uid == setuidRequest.uid
assert response.responseBody ==
ResourceUtil.readByteArrayFromClassPath("org/prebid/server/functional/tracking-pixel.png")

cleanup: "Stop and remove pbs container"
pbsServiceFactory.removeContainer(pbsConfig)
}

def "PBS setuid should failed with tcf when dgpr value is invalid"() {
given: "Default setuid request with account"
def setuidRequest = SetuidRequest.defaultSetuidRequest.tap {
it.account = PBSUtils.randomNumber.toString()
it.uid = UUID.randomUUID().toString()
it.bidder = GENERIC
it.gdpr = "1"
it.gdprConsent = new TcfConsent.Builder()
.setPurposesLITransparency(DEVICE_ACCESS)
.setVendorLegitimateInterest([PBSUtils.getRandomNumberWithExclusion(GENERIC_VENDOR_ID, 0, 65534)])
.build()
}

and: "Flush metrics"
flushMetrics(prebidServerService)

and: "Default uids cookie with generic bidder"
def uidsCookie = UidsCookie.defaultUidsCookie.tap {
it.tempUIDs = [(GENERIC): defaultUidWithExpiry]
}

and: "Save account config with purpose into DB"
def accountConfig = new AccountConfig(
auction: new AccountAuctionConfig(debugAllow: true),
privacy: new AccountPrivacyConfig(gdpr: new AccountGdprConfig(purposes: [(P1): new PurposeConfig(enforcePurpose: NO)], enabled: true)))
def account = new Account(status: ACTIVE, uuid: setuidRequest.account, config: accountConfig)
accountDao.save(account)

when: "PBS processes setuid request"
prebidServerService.sendSetUidRequest(setuidRequest, uidsCookie)

then: "Request should fail with error"
def exception = thrown(PrebidServerException)
assert exception.statusCode == UNAVAILABLE_FOR_LEGAL_REASONS_CODE
assert exception.responseBody == TCF_ERROR_MESSAGE

and: "Metric should be increased usersync.FAMILY.tcf.blocked"
def metric = prebidServerService.sendCollectedMetricsRequest()
assert metric["usersync.${GENERIC.value}.tcf.blocked"] == 1
}

def "PBS setuid should failed with tcf when purpose access device enforced for account"() {
given: "Default setuid request with account"
def setuidRequest = SetuidRequest.defaultSetuidRequest.tap {
Expand All @@ -88,11 +173,14 @@ class GdprSetUidSpec extends PrivacyBaseSpec {
.build()
}

and: "Default uids cookie with rubicon bidder"
and: "Default uids cookie with generic bidder"
def uidsCookie = UidsCookie.defaultUidsCookie.tap {
it.tempUIDs = [(GENERIC): defaultUidWithExpiry]
}

and: "Flush metrics"
flushMetrics(prebidServerService)

and: "Save account config with purpose into DB"
def accountConfig = new AccountConfig(
auction: new AccountAuctionConfig(debugAllow: true),
Expand Down Expand Up @@ -130,11 +218,14 @@ class GdprSetUidSpec extends PrivacyBaseSpec {
.build()
}

and: "Default uids cookie with rubicon bidder"
and: "Default uids cookie with generic bidder"
def uidsCookie = UidsCookie.defaultUidsCookie.tap {
it.tempUIDs = [(GENERIC): defaultUidWithExpiry]
}

and: "Flush metrics"
flushMetrics(prebidServerService)

and: "Save account config with purpose into DB"
def accountConfig = new AccountConfig(
auction: new AccountAuctionConfig(debugAllow: true),
Expand Down Expand Up @@ -176,11 +267,14 @@ class GdprSetUidSpec extends PrivacyBaseSpec {
.build()
}

and: "Default uids cookie with rubicon bidder"
and: "Default uids cookie with generic bidder"
def uidsCookie = UidsCookie.defaultUidsCookie.tap {
it.tempUIDs = [(GENERIC): defaultUidWithExpiry]
}

and: "Flush metrics"
flushMetrics(prebidServerService)

and: "Save account config with purpose into DB"
def accountConfig = new AccountConfig(
auction: new AccountAuctionConfig(debugAllow: true),
Expand Down Expand Up @@ -214,7 +308,7 @@ class GdprSetUidSpec extends PrivacyBaseSpec {
.build()
}

and: "Default uids cookie with rubicon bidder"
and: "Default uids cookie with generic bidder"
def uidsCookie = UidsCookie.defaultUidsCookie.tap {
it.tempUIDs = [(GENERIC): defaultUidWithExpiry]
}
Expand Down
Loading