Skip to content

Commit 4097c12

Browse files
authored
Test: Price floors max rules dimensions (#3646)
* Add functional tests for price floors max rules dimensions
1 parent 7b9fdd4 commit 4097c12

File tree

7 files changed

+441
-24
lines changed

7 files changed

+441
-24
lines changed

src/test/groovy/org/prebid/server/functional/model/config/AccountPriceFloorsConfig.groovy

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ class AccountPriceFloorsConfig {
1515
Boolean adjustForBidAdjustment
1616
Boolean enforceDealFloors
1717
Boolean useDynamicData
18+
Long maxRules
19+
Long maxSchemaDims
1820

1921
@JsonProperty("enforce_floors_rate")
2022
Integer enforceFloorsRateSnakeCase
@@ -24,4 +26,8 @@ class AccountPriceFloorsConfig {
2426
Boolean enforceDealFloorsSnakeCase
2527
@JsonProperty("use_dynamic_data")
2628
Boolean useDynamicDataSnakeCase
29+
@JsonProperty("max_rules")
30+
Long maxRulesSnakeCase
31+
@JsonProperty("max_schema_dims")
32+
Long maxSchemaDimsSnakeCase
2733
}

src/test/groovy/org/prebid/server/functional/model/config/PriceFloorsFetch.groovy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ class PriceFloorsFetch {
2626
Integer periodSec
2727
@JsonProperty("period_sec")
2828
Integer periodSecSnakeCase
29+
Integer maxSchemaDims
30+
@JsonProperty("max_schema_dims")
31+
Integer maxSchemaDimsSnakeCase
2932
}

src/test/groovy/org/prebid/server/functional/model/request/auction/ExtPrebidFloors.groovy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class ExtPrebidFloors {
2020
ExtPrebidPriceFloorEnforcement enforcement
2121
Integer skipRate
2222
PriceFloorData data
23+
Long maxSchemaDims
2324

2425
static ExtPrebidFloors getExtPrebidFloors() {
2526
new ExtPrebidFloors(floorMin: FLOOR_MIN,

src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsBaseSpec.groovy

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,16 @@ abstract class PriceFloorsBaseSpec extends BaseSpec {
5757
maxRules: 0,
5858
maxFileSizeKb: 200,
5959
maxAgeSec: 86400,
60-
periodSec: 3600)
60+
periodSec: 3600,
61+
maxSchemaDims: 5)
6162
def floors = new AccountPriceFloorsConfig(enabled: true,
6263
fetch: fetch,
6364
enforceFloorsRate: 100,
6465
enforceDealFloors: true,
6566
adjustForBidAdjustment: true,
66-
useDynamicData: true)
67+
useDynamicData: true,
68+
maxRules: 0,
69+
maxSchemaDims: 3)
6770
new AccountConfig(auction: new AccountAuctionConfig(priceFloors: floors))
6871
}
6972

src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsFetchingSpec.groovy

Lines changed: 103 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,8 +1299,8 @@ class PriceFloorsFetchingSpec extends PriceFloorsBaseSpec {
12991299
and: "Response should contain error"
13001300
assert response.ext?.errors[PREBID]*.code == [999]
13011301
assert response.ext?.errors[PREBID]*.message ==
1302-
["Failed to parse price floors from request, with a reason : Price floor floorMin " +
1303-
"must be positive float, but was $invalidFloorMin "]
1302+
["Failed to parse price floors from request, with a reason: Price floor floorMin " +
1303+
"must be positive float, but was $invalidFloorMin"]
13041304
}
13051305

13061306
def "PBS should validate rules from request when request doesn't contain modelGroups"() {
@@ -1327,8 +1327,8 @@ class PriceFloorsFetchingSpec extends PriceFloorsBaseSpec {
13271327
and: "Response should contain error"
13281328
assert response.ext?.errors[PREBID]*.code == [999]
13291329
assert response.ext?.errors[PREBID]*.message ==
1330-
["Failed to parse price floors from request, with a reason : Price floor rules " +
1331-
"should contain at least one model group "]
1330+
["Failed to parse price floors from request, with a reason: Price floor rules " +
1331+
"should contain at least one model group"]
13321332
}
13331333

13341334
def "PBS should validate rules from request when request doesn't contain values"() {
@@ -1355,8 +1355,8 @@ class PriceFloorsFetchingSpec extends PriceFloorsBaseSpec {
13551355
and: "Response should contain error"
13561356
assert response.ext?.errors[PREBID]*.code == [999]
13571357
assert response.ext?.errors[PREBID]*.message ==
1358-
["Failed to parse price floors from request, with a reason : Price floor rules values " +
1359-
"can't be null or empty, but were null "]
1358+
["Failed to parse price floors from request, with a reason: Price floor rules values " +
1359+
"can't be null or empty, but were null"]
13601360
}
13611361

13621362
def "PBS should validate rules from request when modelWeight from request is invalid"() {
@@ -1387,8 +1387,8 @@ class PriceFloorsFetchingSpec extends PriceFloorsBaseSpec {
13871387
and: "Response should contain error"
13881388
assert response.ext?.errors[PREBID]*.code == [999]
13891389
assert response.ext?.errors[PREBID]*.message ==
1390-
["Failed to parse price floors from request, with a reason : Price floor modelGroup modelWeight " +
1391-
"must be in range(1-100), but was $invalidModelWeight "]
1390+
["Failed to parse price floors from request, with a reason: Price floor modelGroup modelWeight " +
1391+
"must be in range(1-100), but was $invalidModelWeight"]
13921392
where:
13931393
invalidModelWeight << [0, MAX_MODEL_WEIGHT + 1]
13941394
}
@@ -1426,8 +1426,8 @@ class PriceFloorsFetchingSpec extends PriceFloorsBaseSpec {
14261426
and: "Response should contain error"
14271427
assert response.ext?.errors[PREBID]*.code == [999]
14281428
assert response.ext?.errors[PREBID]*.message ==
1429-
["Failed to parse price floors from request, with a reason : Price floor modelGroup modelWeight " +
1430-
"must be in range(1-100), but was $invalidModelWeight "]
1429+
["Failed to parse price floors from request, with a reason: Price floor modelGroup modelWeight " +
1430+
"must be in range(1-100), but was $invalidModelWeight"]
14311431

14321432
where:
14331433
invalidModelWeight << [0, MAX_MODEL_WEIGHT + 1]
@@ -1466,8 +1466,8 @@ class PriceFloorsFetchingSpec extends PriceFloorsBaseSpec {
14661466
and: "Response should contain error"
14671467
assert response.ext?.errors[PREBID]*.code == [999]
14681468
assert response.ext?.errors[PREBID]*.message ==
1469-
["Failed to parse price floors from request, with a reason : Price floor root skipRate " +
1470-
"must be in range(0-100), but was $invalidSkipRate "]
1469+
["Failed to parse price floors from request, with a reason: Price floor root skipRate " +
1470+
"must be in range(0-100), but was $invalidSkipRate"]
14711471

14721472
where:
14731473
invalidSkipRate << [SKIP_RATE_MIN - 1, SKIP_RATE_MAX + 1]
@@ -1506,8 +1506,8 @@ class PriceFloorsFetchingSpec extends PriceFloorsBaseSpec {
15061506
and: "Response should contain error"
15071507
assert response.ext?.errors[PREBID]*.code == [999]
15081508
assert response.ext?.errors[PREBID]*.message ==
1509-
["Failed to parse price floors from request, with a reason : Price floor data skipRate " +
1510-
"must be in range(0-100), but was $invalidSkipRate "]
1509+
["Failed to parse price floors from request, with a reason: Price floor data skipRate " +
1510+
"must be in range(0-100), but was $invalidSkipRate"]
15111511

15121512
where:
15131513
invalidSkipRate << [SKIP_RATE_MIN - 1, SKIP_RATE_MAX + 1]
@@ -1546,8 +1546,8 @@ class PriceFloorsFetchingSpec extends PriceFloorsBaseSpec {
15461546
and: "Response should contain error"
15471547
assert response.ext?.errors[PREBID]*.code == [999]
15481548
assert response.ext?.errors[PREBID]*.message ==
1549-
["Failed to parse price floors from request, with a reason : Price floor modelGroup skipRate " +
1550-
"must be in range(0-100), but was $invalidSkipRate "]
1549+
["Failed to parse price floors from request, with a reason: Price floor modelGroup skipRate " +
1550+
"must be in range(0-100), but was $invalidSkipRate"]
15511551

15521552
where:
15531553
invalidSkipRate << [SKIP_RATE_MIN - 1, SKIP_RATE_MAX + 1]
@@ -1582,8 +1582,8 @@ class PriceFloorsFetchingSpec extends PriceFloorsBaseSpec {
15821582
and: "Response should contain error"
15831583
assert response.ext?.errors[PREBID]*.code == [999]
15841584
assert response.ext?.errors[PREBID]*.message ==
1585-
["Failed to parse price floors from request, with a reason : Price floor modelGroup default " +
1586-
"must be positive float, but was $invalidDefaultFloorValue "]
1585+
["Failed to parse price floors from request, with a reason: Price floor modelGroup default " +
1586+
"must be positive float, but was $invalidDefaultFloorValue"]
15871587
}
15881588

15891589
def "PBS should not invalidate previously good fetched data when floors provider return invalid data"() {
@@ -2046,6 +2046,91 @@ class PriceFloorsFetchingSpec extends PriceFloorsBaseSpec {
20462046
}
20472047
}
20482048

2049+
def "PBS should validate fetch.max-schema-dims from account config and not reject entire auction"() {
2050+
given: "Default BidRequest"
2051+
def bidRequest = BidRequest.defaultBidRequest
2052+
2053+
and: "Account with enabled fetch, maxSchemaDims in the DB"
2054+
def account = getAccountWithEnabledFetch(bidRequest.accountId).tap {
2055+
config.auction.priceFloors.fetch.maxSchemaDims = maxSchemaDims
2056+
config.auction.priceFloors.fetch.maxSchemaDimsSnakeCase = maxSchemaDimsSnakeCase
2057+
}
2058+
accountDao.save(account)
2059+
2060+
when: "PBS processes auction request"
2061+
def response = floorsPbsService.sendAuctionRequest(bidRequest)
2062+
2063+
then: "Metric alerts.account_config.ACCOUNT.price-floors should be update"
2064+
def metrics = floorsPbsService.sendCollectedMetricsRequest()
2065+
assert metrics[INVALID_CONFIG_METRIC(bidRequest.accountId) as String] == 1
2066+
2067+
and: "PBS floors validation failure should not reject the entire auction"
2068+
assert !response.seatbid?.isEmpty()
2069+
2070+
where:
2071+
maxSchemaDims | maxSchemaDimsSnakeCase
2072+
null | PBSUtils.randomNegativeNumber
2073+
null | PBSUtils.getRandomNumber(20)
2074+
PBSUtils.randomNegativeNumber | null
2075+
PBSUtils.getRandomNumber(20) | null
2076+
}
2077+
2078+
def "PBS should validate price-floor.max-rules from account config and not reject entire auction"() {
2079+
given: "Default BidRequest"
2080+
def bidRequest = BidRequest.defaultBidRequest
2081+
2082+
and: "Account with enabled fetch, maxRules in the DB"
2083+
def account = getAccountWithEnabledFetch(bidRequest.accountId).tap {
2084+
config.auction.priceFloors.maxRules = maxRules
2085+
config.auction.priceFloors.maxRulesSnakeCase = maxRulesSnakeCase
2086+
}
2087+
accountDao.save(account)
2088+
2089+
when: "PBS processes auction request"
2090+
def response = floorsPbsService.sendAuctionRequest(bidRequest)
2091+
2092+
then: "Metric alerts.account_config.ACCOUNT.price-floors should be update"
2093+
def metrics = floorsPbsService.sendCollectedMetricsRequest()
2094+
assert metrics[INVALID_CONFIG_METRIC(bidRequest.accountId) as String] == 1
2095+
2096+
and: "PBS floors validation failure should not reject the entire auction"
2097+
assert !response.seatbid?.isEmpty()
2098+
2099+
where:
2100+
maxRules | maxRulesSnakeCase
2101+
null | PBSUtils.randomNegativeNumber
2102+
PBSUtils.randomNegativeNumber | null
2103+
}
2104+
2105+
def "PBS should validate price-floor.max-schema-dims from account config and not reject entire auction"() {
2106+
given: "Default BidRequest"
2107+
def bidRequest = BidRequest.defaultBidRequest
2108+
2109+
and: "Account with enabled fetch, maxSchemaDims in the DB"
2110+
def account = getAccountWithEnabledFetch(bidRequest.accountId).tap {
2111+
config.auction.priceFloors.maxSchemaDims = maxSchemaDims
2112+
config.auction.priceFloors.maxSchemaDimsSnakeCase = maxSchemaDimsSnakeCase
2113+
}
2114+
accountDao.save(account)
2115+
2116+
when: "PBS processes auction request"
2117+
def response = floorsPbsService.sendAuctionRequest(bidRequest)
2118+
2119+
then: "Metric alerts.account_config.ACCOUNT.price-floors should be update"
2120+
def metrics = floorsPbsService.sendCollectedMetricsRequest()
2121+
assert metrics[INVALID_CONFIG_METRIC(bidRequest.accountId) as String] == 1
2122+
2123+
and: "PBS floors validation failure should not reject the entire auction"
2124+
assert !response.seatbid?.isEmpty()
2125+
2126+
where:
2127+
maxSchemaDims | maxSchemaDimsSnakeCase
2128+
null | PBSUtils.randomNegativeNumber
2129+
null | PBSUtils.getRandomNumber(20)
2130+
PBSUtils.randomNegativeNumber | null
2131+
PBSUtils.getRandomNumber(20) | null
2132+
}
2133+
20492134
static int convertKilobyteSizeToByte(int kilobyteSize) {
20502135
kilobyteSize * 1024
20512136
}

src/test/groovy/org/prebid/server/functional/tests/pricefloors/PriceFloorsRulesSpec.groovy

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -277,10 +277,8 @@ class PriceFloorsRulesSpec extends PriceFloorsBaseSpec {
277277

278278
where:
279279
bidRequest | bothFloorValue | bannerFloorValue | videoFloorValue
280-
bidRequestWithMultipleMediaTypes | 0.6 | PBSUtils.randomFloorValue |
281-
PBSUtils.randomFloorValue
282-
BidRequest.defaultBidRequest | PBSUtils.randomFloorValue | 0.6 |
283-
PBSUtils.randomFloorValue
280+
bidRequestWithMultipleMediaTypes | 0.6 | PBSUtils.randomFloorValue | PBSUtils.randomFloorValue
281+
BidRequest.defaultBidRequest | PBSUtils.randomFloorValue | 0.6 | PBSUtils.randomFloorValue
284282
BidRequest.defaultVideoRequest | PBSUtils.randomFloorValue | PBSUtils.randomFloorValue | 0.6
285283
}
286284

0 commit comments

Comments
 (0)