Skip to content

Commit eed094c

Browse files
mo-alrasclaude
andcommitted
Add WithTotalDefaultRule validation rule
Enforce that the withTotal query parameter, if present, must have a default value of false to optimize query performance. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 3dc5c5e commit eed094c

3 files changed

Lines changed: 106 additions & 0 deletions

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.commercetools.rmf.validators
2+
3+
import io.vrap.rmf.raml.model.resources.Method
4+
import io.vrap.rmf.raml.model.resources.Resource
5+
import org.eclipse.emf.common.util.Diagnostic
6+
import java.util.*
7+
8+
@ValidatorSet
9+
class WithTotalDefaultRule(severity: RuleSeverity, options: List<RuleOption>? = null) : ResourcesRule(severity, options) {
10+
11+
private val exclude: List<String> =
12+
(options?.filter { ruleOption -> ruleOption.type.lowercase(Locale.getDefault()) == RuleOptionType.EXCLUDE.toString() }?.map { ruleOption -> ruleOption.value }?.plus("") ?: defaultExcludes)
13+
14+
override fun caseMethod(method: Method): List<Diagnostic> {
15+
val validationResults: MutableList<Diagnostic> = ArrayList()
16+
17+
method.queryParameters.forEach { queryParameter ->
18+
run {
19+
if (queryParameter.name == "withTotal") {
20+
val resourcePath = (method.eContainer() as Resource).fullUri.template
21+
if (exclude.contains("${method.method.name} $resourcePath").not()) {
22+
val defaultValue = queryParameter.type.default
23+
if (defaultValue == null) {
24+
validationResults.add(
25+
create(
26+
queryParameter,
27+
"Query parameter \"withTotal\" of method \"{0} {1}\" must have a default value of \"false\"",
28+
method.method.name,
29+
resourcePath
30+
)
31+
)
32+
} else if (defaultValue.value.toString() != "false") {
33+
validationResults.add(
34+
create(
35+
queryParameter,
36+
"Query parameter \"withTotal\" of method \"{0} {1}\" must have a default value of \"false\", found \"{2}\"",
37+
method.method.name,
38+
resourcePath,
39+
defaultValue.value.toString()
40+
)
41+
)
42+
}
43+
}
44+
}
45+
}
46+
}
47+
return validationResults
48+
}
49+
50+
companion object : ValidatorFactory<WithTotalDefaultRule> {
51+
private val defaultExcludes by lazy { listOf("") }
52+
53+
@JvmStatic
54+
override fun create(options: List<RuleOption>?): WithTotalDefaultRule {
55+
return WithTotalDefaultRule(RuleSeverity.ERROR, options)
56+
}
57+
58+
@JvmStatic
59+
override fun create(severity: RuleSeverity, options: List<RuleOption>?): WithTotalDefaultRule {
60+
return WithTotalDefaultRule(severity, options)
61+
}
62+
}
63+
}

ctp-validators/src/test/groovy/com/commercetools/rmf/validators/ValidatorRulesTest.groovy

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,4 +528,15 @@ class ValidatorRulesTest extends Specification implements ValidatorFixtures {
528528
then:
529529
result.validationResults.size() == 9
530530
}
531+
532+
def "with total default rule"() {
533+
when:
534+
def validators = Arrays.asList(new ResourcesValidator(Arrays.asList(WithTotalDefaultRule.create(emptyList()))))
535+
def uri = uriFromClasspath("/with-total-default-rule.raml")
536+
def result = new RamlModelBuilder(validators).buildApi(uri)
537+
then:
538+
result.validationResults.size() == 2
539+
result.validationResults[0].message == "Query parameter \"withTotal\" of method \"GET /invalid-resource-true\" must have a default value of \"false\", found \"true\""
540+
result.validationResults[1].message == "Query parameter \"withTotal\" of method \"GET /invalid-resource-no-default\" must have a default value of \"false\""
541+
}
531542
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#%RAML 1.0
2+
title: with total default rule
3+
4+
/valid-resource:
5+
get:
6+
queryParameters:
7+
withTotal:
8+
type: boolean
9+
default: false
10+
required: false
11+
12+
/invalid-resource-true:
13+
get:
14+
queryParameters:
15+
withTotal:
16+
type: boolean
17+
default: true
18+
required: false
19+
20+
/invalid-resource-no-default:
21+
get:
22+
queryParameters:
23+
withTotal:
24+
type: boolean
25+
required: false
26+
27+
/unrelated-resource:
28+
get:
29+
queryParameters:
30+
limit:
31+
type: number
32+
default: 20

0 commit comments

Comments
 (0)