Skip to content

Commit

Permalink
Added support for produces in MicronautConverter (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
cc-jhr committed May 2, 2019
1 parent f340f63 commit 1726a02
Show file tree
Hide file tree
Showing 12 changed files with 375 additions and 2 deletions.
2 changes: 1 addition & 1 deletion docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ There might be various ways to declare or use a feature, so check each converter
| PathParameters | Name of a path parameter. _Example:_ `/todos/{id}`|_(1.0.0)_ |_(1.0.0)_ |_(1.1.0)_ |_(2.0.0)_ |_(2.1.0)_ |_(2.2.0)_ |
| HeaderParameters | Name of a header parameter and whether the parameter is required or not. |_(1.1.0)_ |_(1.1.0)_ |_(1.1.0)_ |_(2.0.0)_ |_(2.1.0)_ |_(2.2.0)_ |
| MatrixParameters | Name of a matrix parameter and whether the parameter is required or not. _Example:_ `/todos;param=value` ||_(2.1.0)_ |_(2.1.0)_ ||_(2.1.0)_ ||
| Produces | Checks the supported media types of the response. |_(1.1.0)_ |_(1.1.0)_ |_(1.1.0)_ |_(2.0.0)_ |_(2.1.0)_ | |
| Produces | Checks the supported media types of the response. |_(1.1.0)_ |_(1.1.0)_ |_(1.1.0)_ |_(2.0.0)_ |_(2.1.0)_ | _(2.2.0)_ |
| Consumes | Checks the supported media types of the request. |_(1.1.0)_ |_(1.1.0)_ |_(1.1.0)_ |_(2.0.0)_ |_(2.1.0)_ |_(2.2.0)_ |
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,49 @@ class MicronautConverter(private val packageName: String) : AbstractEndpointConv
queryParameters = extractQueryParameters(path, method),
pathParameters = extractPathParameters(path, method),
headerParameters = extractHeaderParameters(method),
consumes = extractConsumes(resource, method)
consumes = extractConsumes(resource, method),
produces = extractProduces(resource, method)
)
}

private fun extractProduces(resource: Class<*>, method: Method): Set<String> {
val methodHasNoReturnType = method.returnType.name == "void" || method.returnType.name == "java.lang.Void"

if (methodHasNoReturnType) {
return emptySet()
}

val mediaTypesOnFunction = method.kotlinFunction
?.annotations
?.filterIsInstance<Produces>()
?.flatMap { it.value.map { entry -> entry } }
?.toSet()
.orEmpty()

if (mediaTypesOnFunction.isNotEmpty()) {
return mediaTypesOnFunction
}

val mediaTypesOnControllerByConsumesAnnotation = resource.getAnnotation(Produces::class.java)
?.value
?.toSet()
.orEmpty()

if (mediaTypesOnControllerByConsumesAnnotation.isNotEmpty()) {
return mediaTypesOnControllerByConsumesAnnotation
}

val mediaTypesDefinedByControllerAnnotation = resource.getAnnotation(Controller::class.java)
.produces
.toSet()

if (mediaTypesDefinedByControllerAnnotation.isNotEmpty()) {
return mediaTypesDefinedByControllerAnnotation
}

return setOf("application/json")
}

private fun extractConsumes(resource: Class<*>, method: Method): Set<String> {
val methodAwaitsPayload = method.kotlinFunction
?.parameters
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
package de.codecentric.hikaku.converters.micronaut

import de.codecentric.hikaku.endpoints.Endpoint
import de.codecentric.hikaku.endpoints.HttpMethod.GET
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test

class MicronautConverterProducesTest {

@Nested
inner class DeclaredByControllerOnClass {

@Test
fun `single media type`() {
//given
val specification = setOf(
Endpoint(
path = "/todos",
httpMethod = GET,
produces = setOf(
"text/plain"
)
)
)

//when
val result = MicronautConverter("test.micronaut.produces.onclass.onlycontroller.singlemediatype").conversionResult

//then
assertThat(result).containsExactlyInAnyOrderElementsOf(specification)
}

@Test
fun `multiple media types`() {
//given
val specification = setOf(
Endpoint(
path = "/todos",
httpMethod = GET,
produces = setOf(
"text/plain",
"application/xml"
)
)
)

//when
val result = MicronautConverter("test.micronaut.produces.onclass.onlycontroller.multiplemediatypes").conversionResult

//then
assertThat(result).containsExactlyInAnyOrderElementsOf(specification)
}
}

@Nested
inner class ProducesOnClassOverridesController {

@Test
fun `single media type`() {
//given
val specification = setOf(
Endpoint(
path = "/todos",
httpMethod = GET,
produces = setOf(
"application/xml"
)
)
)

//when
val result = MicronautConverter("test.micronaut.produces.onclass.producesoverridescontroller.singlemediatype").conversionResult

//then
assertThat(result).containsExactlyInAnyOrderElementsOf(specification)
}

@Test
fun `multiple media types`() {
//given
val specification = setOf(
Endpoint(
path = "/todos",
httpMethod = GET,
produces = setOf(
"application/json",
"application/pdf"
)
)
)

//when
val result = MicronautConverter("test.micronaut.produces.onclass.producesoverridescontroller.multiplemediatypes").conversionResult

//then
assertThat(result).containsExactlyInAnyOrderElementsOf(specification)
}
}

@Nested
inner class DeclaredByProducesOnFunction {

@Test
fun `single media type`() {
//given
val specification = setOf(
Endpoint(
path = "/todos",
httpMethod = GET,
produces = setOf(
"text/plain"
)
)
)

//when
val result = MicronautConverter("test.micronaut.produces.onfunction.onlyproduces.singlemediatype").conversionResult

//then
assertThat(result).containsExactlyInAnyOrderElementsOf(specification)
}

@Test
fun `multiple media types`() {
//given
val specification = setOf(
Endpoint(
path = "/todos",
httpMethod = GET,
produces = setOf(
"text/plain",
"application/xml"
)
)
)

//when
val result = MicronautConverter("test.micronaut.produces.onfunction.onlyproduces.multiplemediatypes").conversionResult

//then
assertThat(result).containsExactlyInAnyOrderElementsOf(specification)
}
}

@Nested
inner class ProducesOnFunctionOverridesController {

@Test
fun `single media type`() {
//given
val specification = setOf(
Endpoint(
path = "/todos",
httpMethod = GET,
produces = setOf(
"application/xml"
)
)
)

//when
val result = MicronautConverter("test.micronaut.produces.onfunction.producesoverridescontroller.singlemediatype").conversionResult

//then
assertThat(result).containsExactlyInAnyOrderElementsOf(specification)
}

@Test
fun `multiple media types`() {
//given
val specification = setOf(
Endpoint(
path = "/todos",
httpMethod = GET,
produces = setOf(
"application/json",
"application/pdf"
)
)
)

//when
val result = MicronautConverter("test.micronaut.produces.onfunction.producesoverridescontroller.multiplemediatypes").conversionResult

//then
assertThat(result).containsExactlyInAnyOrderElementsOf(specification)
}
}

@Test
fun `use default media if no produces info has been set`() {
//given
val specification = setOf(
Endpoint(
path = "/todos",
httpMethod = GET,
produces = setOf(
"application/json"
)
)
)

//when
val result = MicronautConverter("test.micronaut.produces.default").conversionResult

//then
assertThat(result).containsExactlyInAnyOrderElementsOf(specification)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package test.micronaut.produces.default

import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import test.micronaut.Todo

@Controller("/todos")
class ProducesDefaultMediaTypeTestController {

@Get
fun todos() = Todo()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package test.micronaut.produces.onclass.onlycontroller.multiplemediatypes

import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import test.micronaut.Todo

@Controller("/todos", produces = ["text/plain", "application/xml"])
class ProducesMultipleMediaTypesTestController {

@Get
fun todos() = Todo()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package test.micronaut.produces.onclass.onlycontroller.singlemediatype

import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import test.micronaut.Todo


@Controller("/todos", produces = ["text/plain"])
class ProducesSingleMediaTypeTestController {

@Get
fun todos() = Todo()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package test.micronaut.produces.onclass.producesoverridescontroller.multiplemediatypes

import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Produces
import test.micronaut.Todo

@Controller("/todos", produces = ["text/plain", "application/xml"])
@Produces("application/json", "application/pdf")
class ProducesMultipleMediaTypesTestController {

@Get
fun todos() = Todo()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package test.micronaut.produces.onclass.producesoverridescontroller.singlemediatype

import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Produces
import test.micronaut.Todo


@Produces("application/xml")
@Controller("/todos", produces = ["text/plain"])
class ProducesSingleMediaTypeTestController {

@Get
fun todos() = Todo()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package test.micronaut.produces.onfunction.onlyproduces.multiplemediatypes

import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Post
import io.micronaut.http.annotation.Produces
import test.micronaut.Todo

@Controller("/todos")
class ProducesMultipleMediaTypesTestController {

@Get
@Produces("text/plain", "application/xml")
fun todos() = Todo()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package test.micronaut.produces.onfunction.onlyproduces.singlemediatype

import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Produces
import test.micronaut.Todo

@Controller("/todos")
class ProducesSingleMediaTypeTestController {

@Get
@Produces("text/plain")
fun todos() = Todo()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package test.micronaut.produces.onfunction.producesoverridescontroller.multiplemediatypes

import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Produces
import test.micronaut.Todo

@Controller("/todos", produces = ["text/plain", "application/xml"])
class ProducesMultipleMediaTypesTestController {

@Get
@Produces("application/json", "application/pdf")
fun todos() = Todo()
}
Loading

0 comments on commit 1726a02

Please sign in to comment.