diff --git a/src/test/groovy/org/prebid/server/functional/tests/BaseSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/BaseSpec.groovy index f80a88d7183..239e6a690e3 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/BaseSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/BaseSpec.groovy @@ -54,8 +54,8 @@ abstract class BaseSpec extends Specification { PBSUtils.getRandomNumber(MIN_TIMEOUT, MAX_TIMEOUT) } - protected static Number getCurrentMetricValue(String name) { - def response = defaultPbsService.sendCollectedMetricsRequest() + protected static Number getCurrentMetricValue(PrebidServerService pbsService = defaultPbsService, String name) { + def response = pbsService.sendCollectedMetricsRequest() response[name] ?: 0 } diff --git a/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsBaseSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsBaseSpec.groovy index cedcffc37d4..14d5058a688 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsBaseSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsBaseSpec.groovy @@ -26,6 +26,7 @@ import org.prebid.server.functional.util.PBSUtils import java.math.RoundingMode import static org.prebid.server.functional.model.request.auction.DistributionChannel.SITE +import static org.prebid.server.functional.model.request.auction.FetchStatus.INPROGRESS @PBSTest abstract class PriceFloorsBaseSpec extends BaseSpec { @@ -113,8 +114,9 @@ abstract class PriceFloorsBaseSpec extends BaseSpec { } protected void cacheFloorsProviderRules(PrebidServerService pbsService = floorsPbsService, BidRequest bidRequest) { - pbsService.sendAuctionRequest(bidRequest) - Thread.sleep(1000) + PBSUtils.waitUntil({ pbsService.sendAuctionRequest(bidRequest).ext?.debug?.resolvedRequest?.ext?.prebid?.floors?.fetchStatus != INPROGRESS }, + 5000, + 1000) } protected void cacheFloorsProviderRules(PrebidServerService pbsService = floorsPbsService, diff --git a/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsCurrencySpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsCurrencySpec.groovy index e9e4a52165e..d82b329fa88 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsCurrencySpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsCurrencySpec.groovy @@ -169,6 +169,9 @@ class PriceFloorsCurrencySpec extends PriceFloorsBaseSpec { and: "PBS fetch rules from floors provider" cacheFloorsProviderRules(pbsService, bidRequest) + and: "Flush metrics" + flushMetrics(pbsService) + when: "PBS processes auction request" def response = pbsService.sendAuctionRequest(bidRequest) @@ -185,8 +188,7 @@ class PriceFloorsCurrencySpec extends PriceFloorsBaseSpec { "to convert from currency $requestFloorCur to desired ad server currency $floorsProviderCur" as String] and: "Metric #GENERAL_ERROR_METRIC should be update" - def metrics = pbsService.sendCollectedMetricsRequest() - assert metrics[GENERAL_ERROR_METRIC] == 1 + assert getCurrentMetricValue(pbsService, GENERAL_ERROR_METRIC) == 1 and: "Bidder request should contain bidFloor, bidFloorCur from request" def bidderRequest = bidder.getBidderRequests(bidRequest.id).last() @@ -319,6 +321,9 @@ class PriceFloorsCurrencySpec extends PriceFloorsBaseSpec { and: "PBS fetch rules from floors provider" cacheFloorsProviderRules(bidRequest) + and: "Flush metrics" + flushMetrics(floorsPbsService) + when: "PBS processes auction request" def response = floorsPbsService.sendAuctionRequest(bidRequest) @@ -329,8 +334,7 @@ class PriceFloorsCurrencySpec extends PriceFloorsBaseSpec { "to convert from currency $requestFloorCur to desired ad server currency $floorsProviderCur" as String] and: "Metric #GENERAL_ERROR_METRIC should be update" - def metrics = floorsPbsService.sendCollectedMetricsRequest() - assert metrics[GENERAL_ERROR_METRIC] == 1 + assert getCurrentMetricValue(floorsPbsService, GENERAL_ERROR_METRIC) == 1 and: "Bidder request should contain bidFloor, bidFloorCur from request" def bidderRequest = bidder.getBidderRequests(bidRequest.id).last() diff --git a/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsFetchingSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsFetchingSpec.groovy index a92088e143d..162cdf30d5e 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsFetchingSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsFetchingSpec.groovy @@ -58,7 +58,7 @@ class PriceFloorsFetchingSpec extends PriceFloorsBaseSpec { cacheFloorsProviderRules(pbsService, bidRequest) when: "PBS processes auction request" - floorsPbsService.sendAuctionRequest(bidRequest) + pbsService.sendAuctionRequest(bidRequest) then: "PBS should fetch data" assert floorsProvider.getRequestCount(bidRequest.app.publisher.id) == 1 @@ -1049,9 +1049,6 @@ class PriceFloorsFetchingSpec extends PriceFloorsBaseSpec { } accountDao.save(account) - and: "PBS fetch rules from floors provider" - cacheFloorsProviderRules(bidRequest) - when: "PBS processes auction request" def response = floorsPbsService.sendAuctionRequest(bidRequest) @@ -1066,6 +1063,62 @@ class PriceFloorsFetchingSpec extends PriceFloorsBaseSpec { "must be positive float, but was $invalidFloorMin "] } + def "PBS should validate rules from request when request doesn't contain modelGroups"() { + given: "Default BidRequest without modelGroups" + def floorValue = PBSUtils.randomFloorValue + def bidRequest = bidRequestWithFloors.tap { + imp[0].bidFloor = floorValue + ext.prebid.floors.data.modelGroups = null + } + + and: "Account with disabled fetch in the DB" + def account = getAccountWithEnabledFetch(bidRequest.site.publisher.id).tap { + config.auction.priceFloors.fetch.enabled = false + } + accountDao.save(account) + + when: "PBS processes auction request" + def response = floorsPbsService.sendAuctionRequest(bidRequest) + + then: "Bidder request bidFloor should correspond to request.imp.bidFloor" + def bidderRequest = bidder.getBidderRequests(bidRequest.id).last() + assert bidderRequest.imp[0].bidFloor == floorValue + + and: "Response should contain error" + assert response.ext?.errors[PREBID]*.code == [999] + assert response.ext?.errors[PREBID]*.message == + ["Failed to parse price floors from request, with a reason : Price floor rules " + + "should contain at least one model group "] + } + + def "PBS should validate rules from request when request doesn't contain values"() { + given: "Default BidRequest without rules" + def floorValue = PBSUtils.randomFloorValue + def bidRequest = bidRequestWithFloors.tap { + imp[0].bidFloor = floorValue + ext.prebid.floors.data.modelGroups[0].values = null + } + + and: "Account with disabled fetch in the DB" + def account = getAccountWithEnabledFetch(bidRequest.site.publisher.id).tap { + config.auction.priceFloors.fetch.enabled = false + } + accountDao.save(account) + + when: "PBS processes auction request" + def response = floorsPbsService.sendAuctionRequest(bidRequest) + + then: "Bidder request bidFloor should correspond to request.imp.bidFloor" + def bidderRequest = bidder.getBidderRequests(bidRequest.id).last() + assert bidderRequest.imp[0].bidFloor == floorValue + + and: "Response should contain error" + assert response.ext?.errors[PREBID]*.code == [999] + assert response.ext?.errors[PREBID]*.message == + ["Failed to parse price floors from request, with a reason : Price floor rules values " + + "can't be null or empty, but were null "] + } + def "PBS should validate rules from request when modelWeight from request is invalid"() { given: "Default BidRequest with floors" def floorValue = PBSUtils.randomFloorValue @@ -1279,9 +1332,6 @@ class PriceFloorsFetchingSpec extends PriceFloorsBaseSpec { } accountDao.save(account) - and: "PBS fetch rules from floors provider" - cacheFloorsProviderRules(bidRequest) - when: "PBS processes auction request" def response = floorsPbsService.sendAuctionRequest(bidRequest) @@ -1376,7 +1426,6 @@ class PriceFloorsFetchingSpec extends PriceFloorsBaseSpec { floorsPbsService.sendAuctionRequest(bidRequest) then: "Bidder request floorMin should correspond to floorMin from request" - assert bidder.getRequestCount(bidRequest.id) == 2 def bidderRequest = bidder.getBidderRequests(bidRequest.id).last() assert bidderRequest.ext?.prebid?.floors?.floorMin == floorMin } diff --git a/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsSignalingSpec.groovy b/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsSignalingSpec.groovy index 8a83875ed3d..9024b5aa1ac 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsSignalingSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsSignalingSpec.groovy @@ -468,7 +468,7 @@ class PriceFloorsSignalingSpec extends PriceFloorsBaseSpec { floorsProvider.setResponse(bidRequest.site.publisher.id, floorsResponse) when: "PBS cache rules and processes auction request" - cacheFloorsProviderRules(bidRequest, floorValue) + cacheFloorsProviderRules(bidRequest) then: "Bidder request should contain 1 modelGroup" def bidderRequest = bidder.getBidderRequests(bidRequest.id).last()