Add Kotlin router DSL and extensions for WebMvc.fn
Closes gh-22697
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.function
|
||||
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.springframework.core.io.ClassPathResource
|
||||
import org.springframework.http.HttpHeaders.*
|
||||
import org.springframework.http.HttpMethod.*
|
||||
import org.springframework.http.MediaType.*
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest
|
||||
|
||||
/**
|
||||
* Tests for WebMvc.fn [RouterFunctionDsl].
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
class RouterFunctionDslTests {
|
||||
|
||||
@Test
|
||||
fun header() {
|
||||
val servletRequest = MockHttpServletRequest()
|
||||
servletRequest.addHeader("bar", "bar")
|
||||
val request = DefaultServerRequest(servletRequest, emptyList())
|
||||
assertTrue(sampleRouter().route(request).isPresent)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun accept() {
|
||||
val servletRequest = MockHttpServletRequest("GET", "/content")
|
||||
servletRequest.addHeader(ACCEPT, APPLICATION_ATOM_XML_VALUE)
|
||||
val request = DefaultServerRequest(servletRequest, emptyList())
|
||||
assertTrue(sampleRouter().route(request).isPresent)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun acceptAndPOST() {
|
||||
val servletRequest = MockHttpServletRequest("POST", "/api/foo/")
|
||||
servletRequest.addHeader(ACCEPT, APPLICATION_JSON_VALUE)
|
||||
val request = DefaultServerRequest(servletRequest, emptyList())
|
||||
assertTrue(sampleRouter().route(request).isPresent)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun contentType() {
|
||||
val servletRequest = MockHttpServletRequest("GET", "/content")
|
||||
servletRequest.addHeader(CONTENT_TYPE, APPLICATION_OCTET_STREAM_VALUE)
|
||||
val request = DefaultServerRequest(servletRequest, emptyList())
|
||||
assertTrue(sampleRouter().route(request).isPresent)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun resourceByPath() {
|
||||
val servletRequest = MockHttpServletRequest("GET", "/org/springframework/web/servlet/function/response.txt")
|
||||
val request = DefaultServerRequest(servletRequest, emptyList())
|
||||
assertTrue(sampleRouter().route(request).isPresent)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun method() {
|
||||
val servletRequest = MockHttpServletRequest("PATCH", "/")
|
||||
val request = DefaultServerRequest(servletRequest, emptyList())
|
||||
assertTrue(sampleRouter().route(request).isPresent)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun path() {
|
||||
val servletRequest = MockHttpServletRequest("GET", "/baz")
|
||||
val request = DefaultServerRequest(servletRequest, emptyList())
|
||||
assertTrue(sampleRouter().route(request).isPresent)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun resource() {
|
||||
val servletRequest = MockHttpServletRequest("GET", "/response.txt")
|
||||
val request = DefaultServerRequest(servletRequest, emptyList())
|
||||
assertTrue(sampleRouter().route(request).isPresent)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun noRoute() {
|
||||
|
||||
val servletRequest = MockHttpServletRequest("GET", "/bar")
|
||||
servletRequest.addHeader(ACCEPT, APPLICATION_PDF_VALUE)
|
||||
servletRequest.addHeader(CONTENT_TYPE, APPLICATION_PDF_VALUE)
|
||||
val request = DefaultServerRequest(servletRequest, emptyList())
|
||||
assertFalse(sampleRouter().route(request).isPresent)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rendering() {
|
||||
val servletRequest = MockHttpServletRequest("GET", "/rendering")
|
||||
val request = DefaultServerRequest(servletRequest, emptyList())
|
||||
assertTrue(sampleRouter().route(request).get().handle(request) is RenderingResponse)
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException::class)
|
||||
fun emptyRouter() {
|
||||
router { }
|
||||
}
|
||||
|
||||
|
||||
private fun sampleRouter() = router {
|
||||
(GET("/foo/") or GET("/foos/")) { req -> handle(req) }
|
||||
"/api".nest {
|
||||
POST("/foo/", ::handleFromClass)
|
||||
PUT("/foo/", :: handleFromClass)
|
||||
PATCH("/foo/") {
|
||||
ok().build()
|
||||
}
|
||||
"/foo/" { handleFromClass(it) }
|
||||
}
|
||||
"/content".nest {
|
||||
accept(APPLICATION_ATOM_XML, ::handle)
|
||||
contentType(APPLICATION_OCTET_STREAM, ::handle)
|
||||
}
|
||||
method(PATCH, ::handle)
|
||||
headers { it.accept().contains(APPLICATION_JSON) }.nest {
|
||||
GET("/api/foo/", ::handle)
|
||||
}
|
||||
headers({ it.header("bar").isNotEmpty() }, ::handle)
|
||||
resources("/org/springframework/web/servlet/function/**",
|
||||
ClassPathResource("/org/springframework/web/servlet/function/response.txt"))
|
||||
resources {
|
||||
if (it.path() == "/response.txt") {
|
||||
ClassPathResource("/org/springframework/web/servlet/function/response.txt")
|
||||
}
|
||||
else {
|
||||
null
|
||||
}
|
||||
}
|
||||
path("/baz", ::handle)
|
||||
GET("/rendering") { RenderingResponse.create("index").build() }
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
private fun handleFromClass(req: ServerRequest) = ServerResponse.ok().build()
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
private fun handle(req: ServerRequest) = ServerResponse.ok().build()
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.function
|
||||
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Test
|
||||
import org.springframework.core.ParameterizedTypeReference
|
||||
import org.springframework.http.MediaType
|
||||
import java.net.InetSocketAddress
|
||||
import java.security.Principal
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Tests for WebMvc.fn [ServerRequest] extensions.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
class ServerRequestExtensionsTests {
|
||||
|
||||
val request = mockk<ServerRequest>()
|
||||
|
||||
val headers = mockk<ServerRequest.Headers>()
|
||||
|
||||
@Test
|
||||
fun `remoteAddressOrNull with value`() {
|
||||
val remoteAddress = mockk<InetSocketAddress>()
|
||||
every { request.remoteAddress() } returns Optional.of(remoteAddress)
|
||||
assertEquals(remoteAddress, request.remoteAddressOrNull())
|
||||
verify { request.remoteAddress() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `remoteAddressOrNull with null`() {
|
||||
every { request.remoteAddress() } returns Optional.empty()
|
||||
assertNull(request.remoteAddressOrNull())
|
||||
verify { request.remoteAddress() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun body() {
|
||||
val body = Arrays.asList("foo", "bar")
|
||||
val typeReference = object: ParameterizedTypeReference<List<String>>() {}
|
||||
every { request.body(typeReference) } returns body
|
||||
assertEquals(body, request.body<List<String>>())
|
||||
verify { request.body(typeReference) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `attributeOrNull with value`() {
|
||||
val attribute = mockk<Any>()
|
||||
every { request.attribute("foo") } returns Optional.of(attribute)
|
||||
assertEquals(attribute, request.attributeOrNull("foo"))
|
||||
verify { request.attribute("foo") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `attributeOrNull with null`() {
|
||||
every { request.attribute("foo") } returns Optional.empty()
|
||||
assertNull(request.attributeOrNull("foo"))
|
||||
verify { request.attribute("foo") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `paramOrNull with value`() {
|
||||
val param = "bar"
|
||||
every { request.param("foo") } returns Optional.of(param)
|
||||
assertEquals(param, request.paramOrNull("foo"))
|
||||
verify { request.param("foo") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `paramOrNull with null`() {
|
||||
every { request.param("foo") } returns Optional.empty()
|
||||
assertNull(request.paramOrNull("foo"))
|
||||
verify { request.param("foo") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `principalOrNull with value`() {
|
||||
val principal = mockk<Principal>()
|
||||
every { request.principal() } returns Optional.of(principal)
|
||||
assertEquals(principal, request.principalOrNull())
|
||||
verify { request.principal() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `principalOrNull with null`() {
|
||||
every { request.principal() } returns Optional.empty()
|
||||
assertNull(request.principalOrNull())
|
||||
verify { request.principal() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `contentLengthOrNull with value`() {
|
||||
val contentLength: Long = 123
|
||||
every { headers.contentLength() } returns OptionalLong.of(contentLength)
|
||||
assertEquals(contentLength, headers.contentLengthOrNull())
|
||||
verify { headers.contentLength() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `contentLengthOrNull with null`() {
|
||||
every { headers.contentLength() } returns OptionalLong.empty()
|
||||
assertNull(headers.contentLengthOrNull())
|
||||
verify { headers.contentLength() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `contentTypeOrNull with value`() {
|
||||
val contentType = mockk<MediaType>()
|
||||
every { headers.contentType() } returns Optional.of(contentType)
|
||||
assertEquals(contentType, headers.contentTypeOrNull())
|
||||
verify { headers.contentType() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `contentTypeOrNull with null`() {
|
||||
val contentType = mockk<MediaType>()
|
||||
every { headers.contentType() } returns Optional.empty()
|
||||
assertNull(headers.contentTypeOrNull())
|
||||
verify { headers.contentType() }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.function
|
||||
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import org.springframework.core.ParameterizedTypeReference
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Tests for WebMvc.fn [ServerResponse] extensions.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
class ServerResponseExtensionsTests {
|
||||
|
||||
@Test
|
||||
fun bodyWithType() {
|
||||
val builder = mockk<ServerResponse.BodyBuilder>()
|
||||
val response = mockk<ServerResponse>()
|
||||
val body = Arrays.asList("foo", "bar")
|
||||
val typeReference = object: ParameterizedTypeReference<List<String>>() {}
|
||||
every { builder.body(body, typeReference) } returns response
|
||||
Assert.assertEquals(response, builder.bodyWithType<List<String>>(body))
|
||||
verify { builder.body(body, typeReference) }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user