Skip to content

Commit

Permalink
Merge branch 'master' into 714-migrate-pascal-case-headers-rule
Browse files Browse the repository at this point in the history
  • Loading branch information
tkrop committed Sep 10, 2018
2 parents dc75b9b + cae0423 commit 5f4b356
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 55 deletions.
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 }
}
3 changes: 0 additions & 3 deletions server/src/main/java/de/zalando/zally/util/PatternUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ object PatternUtil {
private val SNAKE_CASE_PATTERN = "^[a-z0-9]+(?:_[a-z0-9]+)*$".toRegex()
private val KEBAB_CASE_PATTERN = "^[a-z]+(?:-[a-z]+)*$".toRegex()
private val HYPHENATED_PATTERN = "^[A-Za-z0-9.]+(-[A-Za-z0-9.]+)*$".toRegex()
private val VERSION_IN_URL_PATTERN = "(.*)/v[0-9]+(.*)".toRegex()
private val PATH_VARIABLE_PATTERN = "\\{.+}$".toRegex()
private val GENERIC_VERSION_PATTERN = "^\\d+\\.\\d+\\.\\d+$".toRegex()
private val APPLICATION_PROBLEM_JSON_PATTERN = "^application/(problem\\+)?json$".toRegex()
Expand All @@ -36,8 +35,6 @@ object PatternUtil {

fun isHyphenated(input: String): Boolean = input.matches(HYPHENATED_PATTERN)

fun hasVersionInUrl(input: String): Boolean = input.matches(VERSION_IN_URL_PATTERN)

fun isVersion(input: String): Boolean = input.matches(GENERIC_VERSION_PATTERN)

fun isApplicationJsonOrProblemJson(mediaType: String): Boolean =
Expand Down
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()
}
}
8 changes: 0 additions & 8 deletions server/src/test/java/de/zalando/zally/util/PatternUtilTest.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package de.zalando.zally.util

import de.zalando.zally.util.PatternUtil.hasTrailingSlash
import de.zalando.zally.util.PatternUtil.hasVersionInUrl
import de.zalando.zally.util.PatternUtil.isCamelCase
import de.zalando.zally.util.PatternUtil.isHyphenated
import de.zalando.zally.util.PatternUtil.isHyphenatedCamelCase
Expand Down Expand Up @@ -112,13 +111,6 @@ class PatternUtilTest {
assertTrue(isHyphenated("CamelCaseIsNotAcceptableAndShouldBeIllegal"))
}

@Test
fun checkHasVersionInUrl() {
assertTrue(hasVersionInUrl("path/to/v1"))
assertTrue(hasVersionInUrl("path/to/v1/"))
assertFalse(hasVersionInUrl("path/to"))
}

@Test
fun checkGenericIsVersion() {
assertFalse(isVersion("*"))
Expand Down

0 comments on commit 5f4b356

Please sign in to comment.