diff --git a/src/test/groovy/org/prebid/server/functional/testcontainers/PbsConfig.groovy b/src/test/groovy/org/prebid/server/functional/testcontainers/PbsConfig.groovy index 052bcf2f69f..a63039f3416 100644 --- a/src/test/groovy/org/prebid/server/functional/testcontainers/PbsConfig.groovy +++ b/src/test/groovy/org/prebid/server/functional/testcontainers/PbsConfig.groovy @@ -145,5 +145,9 @@ LIMIT 1 "currency-converter.external-rates.refresh-period-ms" : "900000"] } + static Map getTargetingConfig() { + ["settings.targeting.truncate-attr-chars": '255'] + } + private PbsConfig() {} } diff --git a/src/test/groovy/org/prebid/server/functional/testcontainers/container/PrebidServerContainer.groovy b/src/test/groovy/org/prebid/server/functional/testcontainers/container/PrebidServerContainer.groovy index e13fcae3764..0daa6883acf 100644 --- a/src/test/groovy/org/prebid/server/functional/testcontainers/container/PrebidServerContainer.groovy +++ b/src/test/groovy/org/prebid/server/functional/testcontainers/container/PrebidServerContainer.groovy @@ -42,6 +42,7 @@ class PrebidServerContainer extends GenericContainer { << PbsConfig.bidderAliasConfig << PbsConfig.prebidCacheConfig << PbsConfig.mySqlConfig + << PbsConfig.targetingConfig withConfig(commonConfig) withConfig(customConfig) } diff --git a/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy index b745ae53a1f..dd3e010ca0f 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/CacheSpec.groovy @@ -27,7 +27,6 @@ class CacheSpec extends BaseSpec { private static final String PBS_API_HEADER = 'x-pbc-api-key' private static final Integer MAX_DATACENTER_REGION_LENGTH = 4 private static final Integer DEFAULT_UUID_LENGTH = 36 - private static final Integer TARGETING_PARAM_NAME_MAX_LENGTH = 20 private static final String XML_CREATIVE_SIZE_ACCOUNT_METRIC = "account.%s.prebid_cache.creative_size.xml" private static final String JSON_CREATIVE_SIZE_ACCOUNT_METRIC = "account.%s.prebid_cache.creative_size.json" @@ -612,8 +611,8 @@ class CacheSpec extends BaseSpec { it.get("hb_cache_id_generic") it.get("hb_cache_path") == CACHE_PATH it.get("hb_cache_host") == CACHE_HOST - it.get("hb_cache_path_generic".substring(0, TARGETING_PARAM_NAME_MAX_LENGTH)) == CACHE_PATH - it.get("hb_cache_host_generic".substring(0, TARGETING_PARAM_NAME_MAX_LENGTH)) == CACHE_HOST + it.get("hb_cache_path_generic") == CACHE_PATH + it.get("hb_cache_host_generic") == CACHE_HOST } and: "Debug should contain http call" @@ -648,8 +647,8 @@ class CacheSpec extends BaseSpec { it.get("hb_cache_id_generic") it.get("hb_cache_path") == INTERNAL_CACHE_PATH it.get("hb_cache_host") == networkServiceContainer.hostAndPort.toString() - it.get("hb_cache_path_generic".substring(0, TARGETING_PARAM_NAME_MAX_LENGTH)) == INTERNAL_CACHE_PATH - it.get("hb_cache_host_generic".substring(0, TARGETING_PARAM_NAME_MAX_LENGTH)) == networkServiceContainer.hostAndPort.toString() + it.get("hb_cache_path_generic") == INTERNAL_CACHE_PATH + it.get("hb_cache_host_generic") == networkServiceContainer.hostAndPort.toString() } and: "Debug should contain http call" diff --git a/src/test/groovy/org/prebid/server/functional/tests/TargetingSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/TargetingSpec.groovy index 960e05b458e..dc0607e5e31 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/TargetingSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/TargetingSpec.groovy @@ -34,6 +34,7 @@ import org.prebid.server.functional.model.response.auction.Prebid import org.prebid.server.functional.model.response.auction.SeatBid import org.prebid.server.functional.service.PrebidServerException import org.prebid.server.functional.service.PrebidServerService +import org.prebid.server.functional.testcontainers.PbsConfig import org.prebid.server.functional.testcontainers.scaffolding.Bidder import org.prebid.server.functional.util.PBSUtils @@ -57,11 +58,28 @@ class TargetingSpec extends BaseSpec { private static final Integer MAX_AMP_TARGETING_TRUNCATION_LENGTH = 11 private static final String DEFAULT_TARGETING_PREFIX = "hb" private static final Integer TARGETING_PREFIX_LENGTH = 11 - private static final Integer MAX_TRUNCATE_ATTR_CHARS = 255 private static final Integer MAX_BIDS_RANKING = 3 private static final String HB_ENV_AMP = "amp" private static final Integer MAIN_RANK = 1 private static final Integer SUBORDINATE_RANK = 2 + private static final Integer DEFAULT_TRUNCATE_CHARS = 20 + private static final Integer EXTENDED_TRUNCATE_CHARS = PbsConfig.targetingConfig.get('settings.targeting.truncate-attr-chars').toInteger() + private static final Map EMPTY_TARGETING_CONFIG = ['settings.targeting.truncate-attr-chars': null] as Map + private static final Map ONLY_WINNING_BIDS_CONFIG = ["auction.cache.only-winning-bids": "true"] + private static final Map DISABLED_ONLY_WINNING_BIDS_CONFIG = ["auction.cache.only-winning-bids": "false"] + private static final String DROP_PREFIX_WARNING = "Key prefix value is dropped to default. " + + "Decrease custom prefix length or increase truncateattrchars by %s" + private static final String TRUNCATED_WARNING = "The following keys have been truncated:" + + private static final PrebidServerService pbsWithDefaultTargetingLength = pbsServiceFactory.getService(EMPTY_TARGETING_CONFIG) + private static final PrebidServerService pbsWithOnlyWinningBids = pbsServiceFactory.getService(EMPTY_TARGETING_CONFIG + ONLY_WINNING_BIDS_CONFIG) + private static final PrebidServerService pbsWithDisabledOnlyWinningBids = pbsServiceFactory.getService(EMPTY_TARGETING_CONFIG + DISABLED_ONLY_WINNING_BIDS_CONFIG) + + def cleanupSpec() { + pbsServiceFactory.removeContainer(EMPTY_TARGETING_CONFIG + ONLY_WINNING_BIDS_CONFIG) + pbsServiceFactory.removeContainer(EMPTY_TARGETING_CONFIG + DISABLED_ONLY_WINNING_BIDS_CONFIG) + pbsServiceFactory.removeContainer(EMPTY_TARGETING_CONFIG) + } def "PBS should include targeting bidder specific keys when alwaysIncludeDeals is true and deal bid wins"() { given: "Bid request with alwaysIncludeDeals = true" @@ -83,7 +101,7 @@ class TargetingSpec extends BaseSpec { def bidderName = GENERIC.value when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS response targeting contains bidder specific keys" def targetingKeyMap = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -109,7 +127,7 @@ class TargetingSpec extends BaseSpec { bidder.setResponse(bidRequest.id, bidResponse) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS response targeting contains bidder specific keys" def targetingKeyMap = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -134,7 +152,7 @@ class TargetingSpec extends BaseSpec { bidder.setResponse(bidRequest.id, bidResponse) when: "PBS processes auction request" - def response = getEnabledWinBidsPbsService().sendAuctionRequest(bidRequest) + def response = pbsWithOnlyWinningBids.sendAuctionRequest(bidRequest) then: "PBS response targeting does not contain bidder specific keys" def targetingKeyMap = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -162,7 +180,7 @@ class TargetingSpec extends BaseSpec { def bidderName = GENERIC.value when: "PBS processes auction request" - def response = getDisabledWinBidsPbsService().sendAuctionRequest(bidRequest) + def response = pbsWithDisabledOnlyWinningBids.sendAuctionRequest(bidRequest) then: "PBS response targeting contains bidder specific keys" def targetingKeyMap = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -189,7 +207,7 @@ class TargetingSpec extends BaseSpec { } when: "Requesting PBS auction" - def bidResponse = defaultPbsService.sendAuctionRequest(bidRequest) + def bidResponse = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS response shouldn't contain targeting in response" assert !bidResponse.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -213,7 +231,7 @@ class TargetingSpec extends BaseSpec { storedRequestDao.save(storedRequest) when: "PBS processes amp request" - def response = defaultPbsService.sendAmpRequest(ampRequest) + def response = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response shouldn't contain targeting" assert !response.targeting @@ -235,7 +253,7 @@ class TargetingSpec extends BaseSpec { bidder.setResponse(bidRequest.id, bidResponse) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS response targeting includes only one deal specific key" def targetingKeyMap = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -264,7 +282,7 @@ class TargetingSpec extends BaseSpec { storedRequestDao.save(storedRequest) when: "PBS processes amp request" - defaultPbsService.sendAmpRequest(ampRequest) + pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Bidder request should contain amp query params in ext.prebid.amp.data" def bidderRequest = bidder.getBidderRequest(ampStoredRequest.id) @@ -326,7 +344,7 @@ class TargetingSpec extends BaseSpec { storedResponseDao.save(storedResponse) when: "PBS processes amp request" - def response = defaultPbsService.sendAmpRequest(ampRequest) + def response = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response targeting should contain ad server targeting key" verifyAll { @@ -358,7 +376,7 @@ class TargetingSpec extends BaseSpec { storedRequestDao.save(storedRequest) when: "PBS processes amp request" - def response = defaultPbsService.sendAmpRequest(ampRequest) + def response = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response shouldn't contain custom targeting" assert !response.targeting[customKey] @@ -392,7 +410,7 @@ class TargetingSpec extends BaseSpec { storedRequestDao.save(storedRequest) when: "PBS processes amp request" - def response = defaultPbsService.sendAmpRequest(ampRequest) + def response = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response shouldn't contain custom targeting with full naming" assert !response.targeting[customKey] @@ -406,7 +424,7 @@ class TargetingSpec extends BaseSpec { def pbsConfig = [ "adapters.openx.enabled" : "true", "adapters.openx.endpoint": "$networkServiceContainer.rootUri/auction".toString()] - def defaultPbsService = pbsServiceFactory.getService(pbsConfig) + def pbsWithDefaultTargetingLength = pbsServiceFactory.getService(pbsConfig) and: "Default bid request" def accountId = PBSUtils.randomNumber as String @@ -423,13 +441,16 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "Response should contain targeting with corresponding length" assert response.seatbid.bid.ext.prebid.targeting .every(list -> list .every(map -> map.keySet() .every(key -> key.length() <= targetingLength))) + + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(pbsConfig) } def "PBS should truncate targeting corresponding to value in account config when in account define truncate target attr"() { @@ -445,7 +466,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes amp request" - def response = defaultPbsService.sendAmpRequest(ampRequest) + def response = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Response should contain in targeting key not biggest that max size define in account" assert response.targeting.keySet().every { str -> str.length() <= MAX_AMP_TARGETING_TRUNCATION_LENGTH } @@ -467,7 +488,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes amp request" - def response = defaultPbsService.sendAmpRequest(ampRequest) + def response = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Response shouldn't contain targeting" assert response.targeting.isEmpty() @@ -497,7 +518,7 @@ class TargetingSpec extends BaseSpec { and: "Create and save stored response into DB" def storedBidResponse = BidResponse.getDefaultBidResponse(ampStoredRequest).tap { - seatbid[0].bid[0].price = max.plus(1) + seatbid[0].bid[0].price = max + 1 } def storedResponse = new StoredResponse(responseId: storedBidResponseId, storedBidResponse: storedBidResponse) storedResponseDao.save(storedResponse) @@ -507,7 +528,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes amp request" - def response = defaultPbsService.sendAmpRequest(ampRequest) + def response = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Response should contain targeting hb_pb" assert response.targeting["hb_pb"] == String.format("%,.2f", max.setScale(precision, RoundingMode.DOWN)) @@ -530,13 +551,13 @@ class TargetingSpec extends BaseSpec { and: "Create and save stored response into DB" def storedBidResponse = BidResponse.getDefaultBidResponse(bidRequest).tap { - seatbid[0].bid[0].price = max.plus(1) + seatbid[0].bid[0].price = max + 1 } def storedResponse = new StoredResponse(responseId: storedBidResponseId, storedBidResponse: storedBidResponse) storedResponseDao.save(storedResponse) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "Response should contain targeting hb_pb" def targetingKeyMap = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -551,7 +572,7 @@ class TargetingSpec extends BaseSpec { } when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS response should contain default targeting prefix" def targeting = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -572,7 +593,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS response should contain default targeting prefix" def targeting = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -587,7 +608,7 @@ class TargetingSpec extends BaseSpec { } when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS response should contain default targeting prefix" def targeting = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -610,7 +631,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS response should contain default targeting prefix" def targeting = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -629,7 +650,7 @@ class TargetingSpec extends BaseSpec { } when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS response should contain targeting with requested prefix" def targeting = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -650,7 +671,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS response should contain targeting key with specified prefix in account level" def targeting = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -670,7 +691,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS response should contain targeting key with specified prefix in account level" def targeting = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -692,7 +713,7 @@ class TargetingSpec extends BaseSpec { storedRequestDao.save(storedRequest) when: "PBS processes amp request" - def ampResponse = defaultPbsService.sendAmpRequest(ampRequest) + def ampResponse = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response should contain default targeting prefix" def targeting = ampResponse.targeting @@ -718,7 +739,7 @@ class TargetingSpec extends BaseSpec { storedRequestDao.save(storedRequest) when: "PBS processes amp request" - def ampResponse = defaultPbsService.sendAmpRequest(ampRequest) + def ampResponse = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response should contain targeting response with custom prefix" def targeting = ampResponse.targeting @@ -743,7 +764,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes amp request" - def ampResponse = defaultPbsService.sendAmpRequest(ampRequest) + def ampResponse = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response should contain targeting response with custom prefix" def targeting = ampResponse.targeting @@ -768,7 +789,7 @@ class TargetingSpec extends BaseSpec { storedRequestDao.save(storedRequest) when: "PBS processes amp request" - def ampResponse = defaultPbsService.sendAmpRequest(ampRequest) + def ampResponse = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response should contain targeting response with custom prefix" def targeting = ampResponse.targeting @@ -797,7 +818,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes amp request" - def ampResponse = defaultPbsService.sendAmpRequest(ampRequest) + def ampResponse = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response should contain targeting response with custom prefix" def targeting = ampResponse.targeting @@ -820,7 +841,7 @@ class TargetingSpec extends BaseSpec { storedRequestDao.save(storedRequest) when: "PBS processes amp request" - def ampResponse = defaultPbsService.sendAmpRequest(ampRequest) + def ampResponse = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response should contain custom targeting prefix" def targeting = ampResponse.targeting @@ -848,7 +869,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes amp request" - def ampResponse = defaultPbsService.sendAmpRequest(ampRequest) + def ampResponse = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response should contain targeting response with custom prefix" def targeting = ampResponse.targeting @@ -878,7 +899,7 @@ class TargetingSpec extends BaseSpec { storedRequestDao.save(storedRequest) when: "PBS processes amp request" - defaultPbsService.sendAmpRequest(ampRequest) + pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response should contain value from targeting in imp.ext.data" def bidderRequest = bidder.getBidderRequest(ampStoredRequest.id) @@ -886,12 +907,7 @@ class TargetingSpec extends BaseSpec { } def "PBS amp should use long account targeting prefix when settings.targeting.truncate-attr-chars override"() { - given: "PBS config with setting.targeting" - def prefixMaxChars = PBSUtils.getRandomNumber(35, MAX_TRUNCATE_ATTR_CHARS) - def prebidServerService = pbsServiceFactory.getService( - ["settings.targeting.truncate-attr-chars": prefixMaxChars as String]) - - and: "Default AmpRequest" + given: "Default AmpRequest" def ampRequest = AmpRequest.defaultAmpRequest and: "Bid request" @@ -902,13 +918,13 @@ class TargetingSpec extends BaseSpec { storedRequestDao.save(storedRequest) and: "Account in the DB" - def prefix = PBSUtils.getRandomString(prefixMaxChars - TARGETING_PREFIX_LENGTH) + def prefix = PBSUtils.getRandomString(DEFAULT_TRUNCATE_CHARS - TARGETING_PREFIX_LENGTH) def config = new AccountAuctionConfig(targeting: new Targeting(prefix: prefix)) def account = new Account(uuid: ampRequest.account, config: new AccountConfig(auction: config)) accountDao.save(account) when: "PBS processes amp request" - def ampResponse = prebidServerService.sendAmpRequest(ampRequest) + def ampResponse = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response should contain targeting response with custom prefix" def targeting = ampResponse.targeting @@ -917,16 +933,11 @@ class TargetingSpec extends BaseSpec { } def "PBS amp should use long request targeting prefix when settings.targeting.truncate-attr-chars override"() { - given: "PBS config with setting.targeting" - def prefixMaxChars = PBSUtils.getRandomNumber(35, MAX_TRUNCATE_ATTR_CHARS) - def prebidServerService = pbsServiceFactory.getService( - ["settings.targeting.truncate-attr-chars": prefixMaxChars as String]) - - and: "Default AmpRequest" + given: "Default AmpRequest" def ampRequest = AmpRequest.defaultAmpRequest and: "Bid request with prefix" - def prefix = PBSUtils.getRandomString(prefixMaxChars - TARGETING_PREFIX_LENGTH) + def prefix = PBSUtils.getRandomString(EXTENDED_TRUNCATE_CHARS - TARGETING_PREFIX_LENGTH) def ampStoredRequest = BidRequest.defaultBidRequest.tap { ext.prebid.targeting = new Targeting(prefix: prefix) } @@ -936,7 +947,7 @@ class TargetingSpec extends BaseSpec { storedRequestDao.save(storedRequest) when: "PBS processes amp request" - def ampResponse = prebidServerService.sendAmpRequest(ampRequest) + def ampResponse = defaultPbsService.sendAmpRequest(ampRequest) then: "Amp response should contain targeting response with custom prefix" def targeting = ampResponse.targeting @@ -945,19 +956,14 @@ class TargetingSpec extends BaseSpec { } def "PBS auction should use long request targeting prefix when settings.targeting.truncate-attr-chars override"() { - given: "PBS config with setting.targeting" - def prefixMaxChars = PBSUtils.getRandomNumber(35, MAX_TRUNCATE_ATTR_CHARS) - def prebidServerService = pbsServiceFactory.getService( - ["settings.targeting.truncate-attr-chars": prefixMaxChars as String]) - - and: "Bid request with prefix" - def prefix = PBSUtils.getRandomString(prefixMaxChars - TARGETING_PREFIX_LENGTH) + given: "Bid request with prefix" + def prefix = PBSUtils.getRandomString(EXTENDED_TRUNCATE_CHARS - TARGETING_PREFIX_LENGTH) def bidRequest = BidRequest.defaultBidRequest.tap { ext.prebid.targeting = new Targeting(prefix: prefix) } when: "PBS processes auction request" - def bidResponse = prebidServerService.sendAuctionRequest(bidRequest) + def bidResponse = defaultPbsService.sendAuctionRequest(bidRequest) then: "PBS response should contain default targeting prefix" def targeting = bidResponse.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -966,24 +972,19 @@ class TargetingSpec extends BaseSpec { } def "PBS auction should use long account targeting prefix when settings.targeting.truncate-attr-chars override"() { - given: "PBS config with setting.targeting" - def prefixMaxChars = PBSUtils.getRandomNumber(35, MAX_TRUNCATE_ATTR_CHARS) - def prebidServerService = pbsServiceFactory.getService( - ["settings.targeting.truncate-attr-chars": prefixMaxChars as String]) - - and: "Bid request with empty targeting" + given: "Bid request with empty targeting" def bidRequest = BidRequest.defaultBidRequest.tap { ext.prebid.targeting = new Targeting() } and: "Account in the DB" - def prefix = PBSUtils.getRandomString(prefixMaxChars - TARGETING_PREFIX_LENGTH) + def prefix = PBSUtils.getRandomString(EXTENDED_TRUNCATE_CHARS - TARGETING_PREFIX_LENGTH) def config = new AccountAuctionConfig(targeting: new Targeting(prefix: prefix)) def account = new Account(uuid: bidRequest.accountId, config: new AccountConfig(auction: config)) accountDao.save(account) when: "PBS processes auction request" - def bidResponse = prebidServerService.sendAuctionRequest(bidRequest) + def bidResponse = defaultPbsService.sendAuctionRequest(bidRequest) then: "PBS response should contain default targeting prefix" def targeting = bidResponse.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting @@ -992,12 +993,7 @@ class TargetingSpec extends BaseSpec { } def "PBS amp should ignore and add a warning to ext.warnings when value of the account prefix is longer then settings.targeting.truncate-attr-chars"() { - given: "PBS config with setting.targeting" - def targetingChars = PBSUtils.getRandomNumber(2, 10) - def prebidServerService = pbsServiceFactory.getService( - ["settings.targeting.truncate-attr-chars": targetingChars as String]) - - and: "Default AmpRequest" + given: "Default AmpRequest" def ampRequest = AmpRequest.defaultAmpRequest and: "Bid request" @@ -1008,33 +1004,28 @@ class TargetingSpec extends BaseSpec { storedRequestDao.save(storedRequest) and: "Account in the DB" - def prefix = PBSUtils.getRandomString(targetingChars + 1) + def prefix = PBSUtils.getRandomString(DEFAULT_TRUNCATE_CHARS + 1) def config = new AccountAuctionConfig(targeting: new Targeting(prefix: prefix)) def account = new Account(uuid: ampRequest.account, config: new AccountConfig(auction: config)) accountDao.save(account) when: "PBS processes amp request" - def ampResponse = prebidServerService.sendAmpRequest(ampRequest) + def ampResponse = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response should contain warning" - assert ampResponse.ext?.warnings[TARGETING]*.message == ["Key prefix value is dropped to default. " + - "Decrease custom prefix length or increase truncateattrchars by " + - "${prefix.length() + TARGETING_PREFIX_LENGTH - targetingChars}"] + def decreasePrefixLength = prefix.length() + TARGETING_PREFIX_LENGTH - DEFAULT_TRUNCATE_CHARS + assert ampResponse.ext?.warnings[TARGETING]*.message == [DROP_PREFIX_WARNING.formatted(decreasePrefixLength), truncatedMessage()] + } def "PBS amp should ignore and add a warning to ext.warnings when value of the request prefix is longer then settings.targeting.truncate-attr-chars"() { - given: "PBS config with setting.targeting" - def targetingChars = PBSUtils.getRandomNumber(2, 10) - def prebidServerService = pbsServiceFactory.getService( - ["settings.targeting.truncate-attr-chars": targetingChars as String]) - - and: "Default AmpRequest" + given: "Default AmpRequest" def ampRequest = AmpRequest.defaultAmpRequest and: "Bid request with prefix" - def prefix = PBSUtils.getRandomString(targetingChars) + def prefix = PBSUtils.getRandomString(DEFAULT_TRUNCATE_CHARS) def ampStoredRequest = BidRequest.defaultBidRequest.tap { - ext.prebid.targeting = new Targeting(prefix: PBSUtils.getRandomString(targetingChars)) + ext.prebid.targeting = new Targeting(prefix: prefix) } and: "Create and save stored request into DB" @@ -1042,66 +1033,51 @@ class TargetingSpec extends BaseSpec { storedRequestDao.save(storedRequest) when: "PBS processes amp request" - def ampResponse = prebidServerService.sendAmpRequest(ampRequest) + def ampResponse = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response should contain warning" - assert ampResponse.ext?.warnings[TARGETING]*.message == ["Key prefix value is dropped to default. " + - "Decrease custom prefix length or increase truncateattrchars by " + - "${prefix.length() + TARGETING_PREFIX_LENGTH - targetingChars}"] + def decreasePrefixLength = prefix.length() + TARGETING_PREFIX_LENGTH - DEFAULT_TRUNCATE_CHARS + assert ampResponse.ext?.warnings[TARGETING]*.message == [DROP_PREFIX_WARNING.formatted(decreasePrefixLength), truncatedMessage()] } def "PBS auction should ignore and add a warning to ext.warnings when value of the request prefix is longer then settings.targeting.truncate-attr-chars"() { - given: "PBS config with setting.targeting" - def targetingChars = PBSUtils.getRandomNumber(2, 10) - def prebidServerService = pbsServiceFactory.getService( - ["settings.targeting.truncate-attr-chars": targetingChars as String]) - - and: "Bid request with prefix" - def prefixSize = targetingChars + 1 + given: "Bid request with prefix" + def prefixSize = DEFAULT_TRUNCATE_CHARS + 1 def prefix = PBSUtils.getRandomString(prefixSize) def bidRequest = BidRequest.defaultBidRequest.tap { ext.prebid.targeting = new Targeting(prefix: prefix) } when: "PBS processes auction request" - def bidResponse = prebidServerService.sendAuctionRequest(bidRequest) + def bidResponse = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "Bid response should contain warning" def targeting = bidResponse.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting assert !targeting.isEmpty() assert targeting.keySet().every { it -> it.startsWith(DEFAULT_TARGETING_PREFIX) } - assert bidResponse.ext?.warnings[TARGETING]*.message == ["Key prefix value is dropped to default. " + - "Decrease custom prefix length or increase truncateattrchars by " + - "${prefix.length() + TARGETING_PREFIX_LENGTH - targetingChars}"] + assert bidResponse.ext?.warnings[TARGETING]*.message == [DROP_PREFIX_WARNING.formatted(prefix.length() + TARGETING_PREFIX_LENGTH - DEFAULT_TRUNCATE_CHARS)] } def "PBS auction should ignore and add a warning to ext.warnings when value of the account prefix is longer then settings.targeting.truncate-attr-chars"() { - given: "PBS config with setting.targeting" - def targetingChars = PBSUtils.getRandomNumber(2, 10) - def prebidServerService = pbsServiceFactory.getService( - ["settings.targeting.truncate-attr-chars": targetingChars as String]) - - and: "Bid request" + given: "Bid request" def bidRequest = BidRequest.defaultBidRequest.tap { ext.prebid.targeting = new Targeting() } and: "Account in the DB" - def prefix = PBSUtils.getRandomString(targetingChars + 1) + def prefix = PBSUtils.getRandomString(DEFAULT_TRUNCATE_CHARS + 1) def config = new AccountAuctionConfig(targeting: new Targeting(prefix: prefix)) def account = new Account(uuid: bidRequest.accountId, config: new AccountConfig(auction: config)) accountDao.save(account) when: "PBS processes auction request" - def bidResponse = prebidServerService.sendAuctionRequest(bidRequest) + def bidResponse = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "Bid response should contain warning" def targeting = bidResponse.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting assert !targeting.isEmpty() assert targeting.keySet().every { it -> it.startsWith(DEFAULT_TARGETING_PREFIX) } - assert bidResponse.ext?.warnings[TARGETING]*.message == ["Key prefix value is dropped to default. " + - "Decrease custom prefix length or increase truncateattrchars by " + - "${prefix.length() + TARGETING_PREFIX_LENGTH - targetingChars}"] + assert bidResponse.ext?.warnings[TARGETING]*.message == [DROP_PREFIX_WARNING.formatted(prefix.length() + TARGETING_PREFIX_LENGTH - DEFAULT_TRUNCATE_CHARS)] } def "PBS amp should apply data from query to ext.prebid.amp.data"() { @@ -1118,8 +1094,8 @@ class TargetingSpec extends BaseSpec { when: "PBS processes amp request" def unknownValue = PBSUtils.randomString def secondUnknownValue = PBSUtils.randomNumber - defaultPbsService.sendAmpRequestWithAdditionalQueries(ampRequest, ["unknown_field" : unknownValue, - "second_unknown_field": secondUnknownValue]) + pbsWithDefaultTargetingLength.sendAmpRequestWithAdditionalQueries(ampRequest, ["unknown_field" : unknownValue, + "second_unknown_field": secondUnknownValue]) then: "Amp should contain data from query request" def bidderRequests = bidder.getBidderRequest(ampStoredRequest.id) @@ -1140,7 +1116,7 @@ class TargetingSpec extends BaseSpec { storedRequestDao.save(storedRequest) when: "PBS processes amp request" - def ampResponse = defaultPbsService.sendAmpRequest(ampRequest) + def ampResponse = pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Amp response should contain amp hb_env" def targeting = ampResponse.targeting @@ -1158,7 +1134,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes auction request" - defaultPbsService.sendAuctionRequest(bidRequest) + pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "Request should fail with an error" def exception = thrown(PrebidServerException) @@ -1180,7 +1156,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes auction request" - defaultPbsService.sendAuctionRequest(bidRequest) + pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "BidderRequest should include price granularity from bidRequest" def bidderRequest = bidder.getBidderRequest(bidRequest.id) @@ -1210,7 +1186,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes auction request" - defaultPbsService.sendAmpRequest(ampRequest) + pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "BidderRequest should include price granularity from bidRequest" def bidderRequest = bidder.getBidderRequest(ampStoredRequest.id) @@ -1231,7 +1207,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes auction request" - defaultPbsService.sendAuctionRequest(bidRequest) + pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "BidderRequest should include price granularity from account config" def bidderRequest = bidder.getBidderRequest(bidRequest.id) @@ -1252,7 +1228,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes auction request" - defaultPbsService.sendAuctionRequest(bidRequest) + pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "BidderRequest should include price granularity from account config" def bidderRequest = bidder.getBidderRequest(bidRequest.id) @@ -1263,12 +1239,14 @@ class TargetingSpec extends BaseSpec { } def "PBS auction should include price granularity from default account config when original request doesn't contain price granularity"() { - given: "Pbs with default account that include privacySandbox configuration" + given: "Default account that include privacySandbox configuration" def priceGranularity = PBSUtils.getRandomEnum(PriceGranularityType, [UNKNOWN]) def accountAuctionConfig = new AccountAuctionConfig(priceGranularity: priceGranularity) def accountConfig = new AccountConfig(status: ACTIVE, auction: accountAuctionConfig) - def pbsService = pbsServiceFactory.getService( - ["settings.default-account-config": encode(accountConfig)]) + + and: "PBS with default account" + def pbsConfig = ["settings.default-account-config": encode(accountConfig)] + def pbsService = pbsServiceFactory.getService(pbsConfig) and: "Default basic BidRequest" def bidRequest = BidRequest.defaultBidRequest.tap { @@ -1281,6 +1259,9 @@ class TargetingSpec extends BaseSpec { then: "BidderRequest should include price granularity from account config" def bidderRequest = bidder.getBidderRequest(bidRequest.id) assert bidderRequest?.ext?.prebid?.targeting?.priceGranularity == PriceGranularity.getDefault(priceGranularity) + + cleanup: "Stop and remove pbs container" + pbsServiceFactory.removeContainer(pbsConfig) } def "PBS auction should include include default price granularity when original request and account config doesn't contain price granularity"() { @@ -1295,7 +1276,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes auction request" - defaultPbsService.sendAuctionRequest(bidRequest) + pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "BidderRequest should include default price granularity" def bidderRequest = bidder.getBidderRequest(bidRequest.id) @@ -1327,7 +1308,7 @@ class TargetingSpec extends BaseSpec { accountDao.save(account) when: "PBS processes auction request" - defaultPbsService.sendAmpRequest(ampRequest) + pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "Request should fail with an error" def exception = thrown(PrebidServerException) @@ -1354,7 +1335,7 @@ class TargetingSpec extends BaseSpec { storedRequestDao.save(storedRequest) when: "PBS processes amp request" - defaultPbsService.sendAmpRequest(ampRequest) + pbsWithDefaultTargetingLength.sendAmpRequest(ampRequest) then: "BidderRequest should include price granularity from account config" def bidderRequest = bidder.getBidderRequest(ampStoredRequest.id) @@ -1388,7 +1369,7 @@ class TargetingSpec extends BaseSpec { bidder.setResponse(bidRequest.id, bidResponse) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS bids in response shouldn't contain ranks" assert response?.seatbid?.bid?.ext?.prebid?.rank?.flatten() == [null] * MAX_BIDS_RANKING @@ -1433,7 +1414,7 @@ class TargetingSpec extends BaseSpec { bidder.setResponse(bidRequest.id, bidResponse) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS should rank single bid" verifyAll(response.seatbid.first.bid) { @@ -1473,7 +1454,7 @@ class TargetingSpec extends BaseSpec { bidder.setResponse(bidRequest.id, bidResponse) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS should rank single bid" verifyAll(response.seatbid.first.bid) { @@ -1514,7 +1495,7 @@ class TargetingSpec extends BaseSpec { bidder.setResponse(bidRequest.id, bidResponse) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS should rank bid with higher price as top priority" def bids = response.seatbid.first.bid @@ -1600,7 +1581,7 @@ class TargetingSpec extends BaseSpec { bidder.setResponse(bidRequest.id, bidResponse) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS should rank bid with higher price as top priority" def bids = response.seatbid.first.bid @@ -1702,7 +1683,7 @@ class TargetingSpec extends BaseSpec { bidder.setResponse(bidRequest.id, bidResponse) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS should rank bids for first imp" def bids = response.seatbid.first.bid @@ -1751,7 +1732,7 @@ class TargetingSpec extends BaseSpec { bidder.setResponse(bidRequest.id, bidResponse) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS should rank bid with higher price as top priority" def bids = response.seatbid.first.bid @@ -1802,7 +1783,7 @@ class TargetingSpec extends BaseSpec { bidder.setResponse(bidRequest.id, bidResponse) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS should rank bid with higher price as top priority" def bids = response.seatbid.first.bid @@ -1843,7 +1824,7 @@ class TargetingSpec extends BaseSpec { bidder.setResponse(bidRequest.id, bidResponse) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS bids in response shouldn't contain ranks" assert response?.seatbid?.bid?.ext?.prebid?.rank?.flatten() == [null] * MAX_BIDS_RANKING @@ -1882,7 +1863,7 @@ class TargetingSpec extends BaseSpec { storedResponseDao.save(storedResponse) when: "PBS processes auction request" - def response = defaultPbsService.sendAuctionRequest(bidRequest) + def response = pbsWithDefaultTargetingLength.sendAuctionRequest(bidRequest) then: "PBS should copy bid ranked from stored response" def bids = response.seatbid.first.bid @@ -1900,23 +1881,19 @@ class TargetingSpec extends BaseSpec { ] } - Account createAccountWithPriceGranularity(String accountId, PriceGranularityType priceGranularity) { + private static Account createAccountWithPriceGranularity(String accountId, PriceGranularityType priceGranularity) { def accountAuctionConfig = new AccountAuctionConfig(priceGranularity: priceGranularity) def accountConfig = new AccountConfig(status: ACTIVE, auction: accountAuctionConfig) new Account(uuid: accountId, config: accountConfig) } - Account getAccountConfigWithAuctionRanking(String accountId, Boolean auctionRankingEnablement = true) { + private static Account getAccountConfigWithAuctionRanking(String accountId, Boolean auctionRankingEnablement = true) { def accountAuctionConfig = new AccountAuctionConfig(ranking: new AccountRankingConfig(enabled: auctionRankingEnablement)) def accountConfig = new AccountConfig(status: ACTIVE, auction: accountAuctionConfig) new Account(uuid: accountId, config: accountConfig) } - private static PrebidServerService getEnabledWinBidsPbsService() { - pbsServiceFactory.getService(["auction.cache.only-winning-bids": "true"]) - } - - private static PrebidServerService getDisabledWinBidsPbsService() { - pbsServiceFactory.getService(["auction.cache.only-winning-bids": "false"]) + private static def truncatedMessage(List keys = ["hb_cache_host_${GENERIC}", "hb_cache_path_${GENERIC}"]) { + "$TRUNCATED_WARNING ${keys.join(', ')}" } }