diff --git a/src/main/java/org/prebid/server/auction/CpmRange.java b/src/main/java/org/prebid/server/auction/CpmRange.java index 00133373474..0310f956025 100644 --- a/src/main/java/org/prebid/server/auction/CpmRange.java +++ b/src/main/java/org/prebid/server/auction/CpmRange.java @@ -1,7 +1,6 @@ package org.prebid.server.auction; import org.apache.commons.lang3.ObjectUtils; -import org.apache.commons.lang3.StringUtils; import org.prebid.server.proto.openrtb.ext.request.ExtGranularityRange; import org.prebid.server.settings.model.Account; import org.prebid.server.settings.model.AccountAuctionConfig; @@ -19,6 +18,8 @@ */ public class CpmRange { + public static final String DEFAULT_CPM = "0.0"; + private static final Locale LOCALE = Locale.US; private static final int DEFAULT_PRECISION = 2; @@ -30,7 +31,7 @@ private CpmRange() { */ public static String fromCpm(BigDecimal cpm, PriceGranularity priceGranularity, Account account) { final BigDecimal value = fromCpmAsNumber(cpm, priceGranularity, account); - return value != null ? format(value, priceGranularity.getPrecision()) : StringUtils.EMPTY; + return value != null ? format(value, priceGranularity.getPrecision()) : DEFAULT_CPM; } /** diff --git a/src/main/java/org/prebid/server/auction/TargetingKeywordsCreator.java b/src/main/java/org/prebid/server/auction/TargetingKeywordsCreator.java index 30507e4072c..16af4e15d71 100644 --- a/src/main/java/org/prebid/server/auction/TargetingKeywordsCreator.java +++ b/src/main/java/org/prebid/server/auction/TargetingKeywordsCreator.java @@ -78,8 +78,6 @@ public class TargetingKeywordsCreator { */ private static final String FORMAT_KEY = "_format"; - private static final String DEFAULT_CPM = "0.0"; - private final PriceGranularity priceGranularity; private final boolean includeWinners; private final boolean includeBidderKeys; @@ -206,7 +204,7 @@ private Map makeFor(String bidder, final String roundedCpm = isPriceGranularityValid() ? CpmRange.fromCpm(price, priceGranularity, account) - : DEFAULT_CPM; + : CpmRange.DEFAULT_CPM; keywordMap.put(this.keyPrefix + PB_KEY, roundedCpm); 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 dc0607e5e31..d9d337b3c27 100644 --- a/src/test/groovy/org/prebid/server/functional/tests/TargetingSpec.groovy +++ b/src/test/groovy/org/prebid/server/functional/tests/TargetingSpec.groovy @@ -62,6 +62,7 @@ class TargetingSpec extends BaseSpec { 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 String EMPTY_CPM = "0.0" 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 @@ -564,6 +565,30 @@ class TargetingSpec extends BaseSpec { assert targetingKeyMap["hb_pb"] == String.format("%,.2f", max.setScale(precision, RoundingMode.DOWN)) } + def "PBS auction shouldn't delete bid and update targeting if price equal zero and dealId present"() { + given: "Default bid request with stored response" + def bidRequest = BidRequest.defaultBidRequest.tap { + ext.prebid.targeting = Targeting.createWithAllValuesSetTo(true) + } + + and: "Bid response with zero price" + def bidResponse = BidResponse.getDefaultBidResponse(bidRequest).tap { + seatbid[0].bid[0].price = 0 + seatbid[0].bid[0].dealid = PBSUtils.randomString + } + + and: "Set bidder response" + bidder.setResponse(bidRequest.id, bidResponse) + + when: "PBS processes auction request" + def response = defaultPbsService.sendAuctionRequest(bidRequest) + + then: "Response should contain proper targeting hb_pb" + def targetingKeyMap = response.seatbid?.first()?.bid?.first()?.ext?.prebid?.targeting + assert targetingKeyMap["hb_pb"] == EMPTY_CPM + assert targetingKeyMap["hb_pb_generic"] == EMPTY_CPM + } + def "PBS auction should use default targeting prefix when ext.prebid.targeting.prefix is biggest that twenty"() { given: "Bid request with long targeting prefix" def prefix = PBSUtils.getRandomString(30) diff --git a/src/test/java/org/prebid/server/auction/CpmRangeTest.java b/src/test/java/org/prebid/server/auction/CpmRangeTest.java index 48028175363..c44ae1edd14 100644 --- a/src/test/java/org/prebid/server/auction/CpmRangeTest.java +++ b/src/test/java/org/prebid/server/auction/CpmRangeTest.java @@ -21,6 +21,20 @@ public class CpmRangeTest { + @Test + public void fromCpmShouldReturnZeroValueIfPriceDoesNotFitToRange() { + // given + final PriceGranularity priceGranularity = createFromExtPriceGranularity( + ExtPriceGranularity.of(null, singletonList(ExtGranularityRange.of(BigDecimal.valueOf(3), + BigDecimal.valueOf(0.01))))); + + // when + final String result = CpmRange.fromCpm(BigDecimal.valueOf(-2.0), priceGranularity, givenAccount()); + + // then + assertThat(result).isEqualTo("0.0"); + } + @Test public void fromCpmShouldReturnMaxRangeIfCpmExceedsIt() { assertThat(CpmRange.fromCpm(BigDecimal.valueOf(21), createFromString("auto"), givenAccount()))