-
Notifications
You must be signed in to change notification settings - Fork 117
Expand file tree
/
Copy pathMockMvcAutoRestDocumentationWrapper.kt
More file actions
106 lines (89 loc) · 4.16 KB
/
MockMvcAutoRestDocumentationWrapper.kt
File metadata and controls
106 lines (89 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package com.epages.restdocs.apispec
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.springframework.mock.web.MockHttpServletRequest
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler
import org.springframework.restdocs.operation.preprocess.Preprocessors
import org.springframework.restdocs.payload.FieldDescriptor
import org.springframework.restdocs.payload.PayloadDocumentation
import org.springframework.test.web.servlet.ResultActions
import org.springframework.web.servlet.HandlerMapping
object MockMvcAutoRestDocumentationWrapper {
@JvmStatic
fun createDocs(
tag: String,
identifier: String,
description: String,
resultActions: ResultActions
): RestDocumentationResultHandler {
val resourceSnippetParametersBuilder = ResourceSnippetParametersBuilder().tags(tag).description(description)
val request = resultActions.andReturn().request
val requestNode: JsonNode? =
request.contentAsString?.let { jacksonObjectMapper().readTree(request.contentAsString) }
val requestFieldDescriptors = createFieldDescriptors(requestNode)
val response = resultActions.andReturn().response
val responseNode: JsonNode? =
response.contentAsString.let { jacksonObjectMapper().readTree(response.contentAsString) }
val responseFieldDescriptors = createFieldDescriptors(responseNode)
val requestParameter = createParameters(request, ParameterType.QUERY)
val requestPathParameter = createParameters(request, ParameterType.PATH)
resourceSnippetParametersBuilder.requestFields(requestFieldDescriptors)
resourceSnippetParametersBuilder.queryParameters(requestParameter)
resourceSnippetParametersBuilder.pathParameters(requestPathParameter)
resourceSnippetParametersBuilder.responseFields(responseFieldDescriptors)
return MockMvcRestDocumentationWrapper.document(
identifier,
Preprocessors.preprocessRequest(Preprocessors.prettyPrint()),
Preprocessors.preprocessResponse(Preprocessors.prettyPrint()),
ResourceDocumentation.resource(resourceSnippetParametersBuilder.build())
)
}
private fun createFieldDescriptors(jsonNode: JsonNode?, parentPath: String = ""): List<FieldDescriptor> {
if (jsonNode == null) return emptyList()
val fieldDescriptors = mutableListOf<FieldDescriptor>()
val iterator = jsonNode.fields()
while (iterator.hasNext()) {
val entry = iterator.next()
val key = entry.key
val value = entry.value
val path = if (parentPath.isEmpty()) key else "$parentPath.$key"
when {
value.isObject -> {
fieldDescriptors.addAll(createFieldDescriptors(value, path))
}
value.isArray -> {
value.forEach { item ->
if (item.isObject) {
fieldDescriptors.addAll(createFieldDescriptors(item, "$path.[]."))
}
}
}
else -> {
fieldDescriptors.add(
PayloadDocumentation.fieldWithPath(path).description(value.asText())
)
}
}
}
return fieldDescriptors
}
private fun createParameters(
request: MockHttpServletRequest,
type: ParameterType
): List<ParameterDescriptorWithType> {
return if (type == ParameterType.QUERY) {
request.parameterMap.map { (key, value) ->
ResourceDocumentation.parameterWithName(key).description(value.joinToString())
}
} else {
val uriVars = request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE) as? Map<*, *>
return uriVars?.entries?.map { (key, value) ->
ResourceDocumentation.parameterWithName(key.toString()).description("$value")
}?.toList() ?: listOf()
}
}
private enum class ParameterType {
PATH,
QUERY
}
}