-
Notifications
You must be signed in to change notification settings - Fork 141
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into 714-migrate-pascal-case-headers-rule
- Loading branch information
Showing
4 changed files
with
66 additions
and
55 deletions.
There are no files selected for viewing
33 changes: 22 additions & 11 deletions
33
server/src/main/java/de/zalando/zally/rule/zalando/NoVersionInUriRule.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,35 @@ | ||
package de.zalando.zally.rule.zalando | ||
|
||
import de.zalando.zally.rule.api.Check | ||
import de.zalando.zally.rule.api.Context | ||
import de.zalando.zally.rule.api.Rule | ||
import de.zalando.zally.rule.api.Severity | ||
import de.zalando.zally.rule.api.Violation | ||
import de.zalando.zally.util.PatternUtil | ||
import io.swagger.models.Swagger | ||
import io.swagger.v3.oas.models.OpenAPI | ||
import io.swagger.v3.oas.models.PathItem | ||
import io.swagger.v3.oas.models.servers.Server | ||
|
||
@Rule( | ||
ruleSet = ZalandoRuleSet::class, | ||
id = "115", | ||
severity = Severity.MUST, | ||
title = "Do Not Use URI Versioning" | ||
ruleSet = ZalandoRuleSet::class, | ||
id = "115", | ||
severity = Severity.MUST, | ||
title = "Do Not Use URI Versioning" | ||
) | ||
class NoVersionInUriRule { | ||
private val description = "basePath attribute contains version number" | ||
private val description = "URL contains version number" | ||
private val versionRegex = "(.*)v[0-9]+(.*)".toRegex() | ||
|
||
@Check(severity = Severity.MUST) | ||
fun validate(swagger: Swagger): Violation? { | ||
val hasVersion = swagger.basePath != null && PatternUtil.hasVersionInUrl(swagger.basePath) | ||
return if (hasVersion) Violation(description, emptyList()) else null | ||
} | ||
fun checkServerURLs(context: Context): List<Violation> = | ||
(violatingServers(context.api) + violatingPaths(context.api)) | ||
.map { context.violation(description, it) } | ||
|
||
private fun violatingServers(api: OpenAPI): Collection<Server> = | ||
api.servers.orEmpty() | ||
.filter { it.url.matches(versionRegex) } | ||
|
||
private fun violatingPaths(api: OpenAPI): Collection<PathItem> = | ||
api.paths.orEmpty().entries | ||
.filter { (path, _) -> path.matches(versionRegex) } | ||
.map { (_, pathEntry) -> pathEntry } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 44 additions & 33 deletions
77
server/src/test/java/de/zalando/zally/rule/zalando/NoVersionInUriRuleTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,62 @@ | ||
package de.zalando.zally.rule.zalando | ||
|
||
import de.zalando.zally.rule.api.Violation | ||
import io.swagger.models.Swagger | ||
import de.zalando.zally.getOpenApiContextFromContent | ||
import org.assertj.core.api.Assertions.assertThat | ||
import org.intellij.lang.annotations.Language | ||
import org.junit.Test | ||
|
||
class NoVersionInUriRuleTest { | ||
|
||
private val rule = NoVersionInUriRule() | ||
|
||
val expectedViolation = Violation( | ||
"basePath attribute contains version number", | ||
emptyList()) | ||
|
||
@Test | ||
fun returnsViolationsWhenVersionIsInTheBeginingOfBasePath() { | ||
val swagger = Swagger().apply { basePath = "/v1/tests" } | ||
assertThat(rule.validate(swagger)).isEqualTo(expectedViolation) | ||
} | ||
|
||
@Test | ||
fun returnsViolationsWhenVersionIsInTheMiddleOfBasePath() { | ||
val swagger = Swagger().apply { basePath = "/api/v1/tests" } | ||
assertThat(rule.validate(swagger)).isEqualTo(expectedViolation) | ||
} | ||
|
||
@Test | ||
fun returnsViolationsWhenVersionIsInTheEndOfBasePath() { | ||
val swagger = Swagger().apply { basePath = "/api/v1" } | ||
assertThat(rule.validate(swagger)).isEqualTo(expectedViolation) | ||
} | ||
|
||
@Test | ||
fun returnsViolationsWhenVersionIsBig() { | ||
val swagger = Swagger().apply { basePath = "/v1024/tests" } | ||
assertThat(rule.validate(swagger)).isEqualTo(expectedViolation) | ||
fun `checkServerURLs should return a violation if a server URL contains a version as base path`() { | ||
@Language("YAML") | ||
val spec = """ | ||
openapi: 3.0.1 | ||
servers: | ||
- url: "https://inter.net/api/v1.0" | ||
""".trimIndent() | ||
val context = getOpenApiContextFromContent(spec) | ||
|
||
val violations = rule.checkServerURLs(context) | ||
|
||
assertThat(violations).isNotEmpty | ||
assertThat(violations).hasSize(1) | ||
assertThat(violations[0].description).contains("URL contains version number") | ||
assertThat(violations[0].pointer.toString()).isEqualTo("/servers/0") | ||
} | ||
|
||
@Test | ||
fun returnsEmptyViolationListWhenNoVersionFoundInURL() { | ||
val swagger = Swagger().apply { basePath = "/violations/" } | ||
assertThat(rule.validate(swagger)).isNull() | ||
fun `checkServerURLs should return a violation if (sub) resource names contain version suffix`() { | ||
@Language("YAML") | ||
val spec = """ | ||
openapi: 3.0.1 | ||
paths: | ||
/shop/orders-v1/{order-id}: {} | ||
""".trimIndent() | ||
val context = getOpenApiContextFromContent(spec) | ||
|
||
val violations = rule.checkServerURLs(context) | ||
|
||
assertThat(violations).isNotEmpty | ||
assertThat(violations).hasSize(1) | ||
assertThat(violations[0].description).contains("URL contains version number") | ||
assertThat(violations[0].pointer.toString()).isEqualTo("/paths/~1shop~1orders-v1~1{order-id}") | ||
} | ||
|
||
@Test | ||
fun returnsEmptyViolationListWhenBasePathIsNull() { | ||
val swagger = Swagger() | ||
assertThat(rule.validate(swagger)).isNull() | ||
fun `checkServerURLs should return no violations if a server URL does not contain a version as base path`() { | ||
@Language("YAML") | ||
val spec = """ | ||
openapi: 3.0.1 | ||
servers: | ||
- url: "https://inter.net/api/" | ||
""".trimIndent() | ||
val context = getOpenApiContextFromContent(spec) | ||
|
||
val violations = rule.checkServerURLs(context) | ||
|
||
assertThat(violations).isEmpty() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters