Skip to content

Commit fb47811

Browse files
Support beneathPath in MockMvcRestDocumentationWrapper (#250)
Co-authored-by: Phil Owen <[email protected]>
1 parent c631886 commit fb47811

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

restdocs-api-spec-mockmvc/src/test/kotlin/com/epages/restdocs/apispec/MockMvcRestDocumentationWrapperIntegrationTest.kt

+43
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import org.springframework.restdocs.hypermedia.HypermediaDocumentation.links
1717
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document
1818
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post
1919
import org.springframework.restdocs.operation.preprocess.OperationRequestPreprocessor
20+
import org.springframework.restdocs.payload.PayloadDocumentation.beneathPath
2021
import org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath
2122
import org.springframework.restdocs.payload.PayloadDocumentation.requestFields
2223
import org.springframework.restdocs.payload.PayloadDocumentation.responseFields
@@ -51,6 +52,15 @@ class MockMvcRestDocumentationWrapperIntegrationTest(@Autowired private val mock
5152
thenSnippetFileExists()
5253
}
5354

55+
@Test
56+
fun should_document_both_restdocs_and_resource_with_path() {
57+
givenEndpointInvoked()
58+
59+
whenDocumentedWithPayloadSubsectionExtractor()
60+
61+
thenSnippetFileExists()
62+
}
63+
5464
@Test
5565
fun should_document_using_the_passed_raml_snippet() {
5666
givenEndpointInvoked()
@@ -250,6 +260,39 @@ class MockMvcRestDocumentationWrapperIntegrationTest(@Autowired private val mock
250260
)
251261
}
252262

263+
@Throws(Exception::class)
264+
private fun whenDocumentedWithPayloadSubsectionExtractor() {
265+
val operationRequestPreprocessor = OperationRequestPreprocessor { r -> r }
266+
resultActions
267+
.andDo(
268+
MockMvcRestDocumentationWrapper.document(
269+
identifier = operationName,
270+
privateResource = true,
271+
requestPreprocessor = operationRequestPreprocessor,
272+
snippets = arrayOf(
273+
requestFields(fieldDescriptors().fieldDescriptors),
274+
responseFields(
275+
fieldWithPath("comment").description("the comment"),
276+
fieldWithPath("flag").description("the flag"),
277+
fieldWithPath("count").description("the count"),
278+
fieldWithPath("id").description("id"),
279+
subsectionWithPath("_links").ignored()
280+
),
281+
responseFields(
282+
beneathPath("_links").withSubsectionId("beneath-links"),
283+
fieldWithPath("self").description("self link"),
284+
fieldWithPath("self.href").description("self link href"),
285+
subsectionWithPath("multiple").ignored(),
286+
),
287+
links(
288+
linkWithRel("self").description("some"),
289+
linkWithRel("multiple").description("multiple")
290+
)
291+
)
292+
)
293+
)
294+
}
295+
253296
@Throws(Exception::class)
254297
private fun whenDocumentedWithResourceSnippetDetails() {
255298
val operationRequestPreprocessor = OperationRequestPreprocessor { r -> r }

restdocs-api-spec/src/main/kotlin/com/epages/restdocs/apispec/DescriptorExtractor.kt

+14-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import org.springframework.restdocs.hypermedia.LinkDescriptor
77
import org.springframework.restdocs.hypermedia.LinksSnippet
88
import org.springframework.restdocs.payload.AbstractFieldsSnippet
99
import org.springframework.restdocs.payload.FieldDescriptor
10+
import org.springframework.restdocs.payload.FieldPathPayloadSubsectionExtractor
11+
import org.springframework.restdocs.payload.PayloadDocumentation
12+
import org.springframework.restdocs.payload.PayloadSubsectionExtractor
1013
import org.springframework.restdocs.request.AbstractParametersSnippet
1114
import org.springframework.restdocs.request.ParameterDescriptor
1215
import org.springframework.restdocs.snippet.AbstractDescriptor
@@ -32,7 +35,17 @@ internal object DescriptorExtractor {
3235
try {
3336
val getFieldDescriptors = AbstractFieldsSnippet::class.java.getDeclaredMethod("getFieldDescriptors")
3437
getFieldDescriptors.isAccessible = true
35-
return getFieldDescriptors.invoke(snippet) as List<FieldDescriptor>
38+
var descriptors = getFieldDescriptors.invoke(snippet) as List<FieldDescriptor>
39+
val getSubsectionExtractor = AbstractFieldsSnippet::class.java.getDeclaredMethod("getSubsectionExtractor")
40+
getSubsectionExtractor.isAccessible = true
41+
val payloadSubsectionExtractor = getSubsectionExtractor.invoke(snippet) as PayloadSubsectionExtractor<*>?
42+
if (payloadSubsectionExtractor is FieldPathPayloadSubsectionExtractor) {
43+
val getFieldPath = FieldPathPayloadSubsectionExtractor::class.java.getDeclaredMethod("getFieldPath")
44+
getFieldPath.isAccessible = true
45+
val fieldPath = getFieldPath.invoke(payloadSubsectionExtractor) as String
46+
descriptors = PayloadDocumentation.applyPathPrefix("$fieldPath.", descriptors)
47+
}
48+
return descriptors
3649
} catch (e: NoSuchMethodException) {
3750
e.printStackTrace()
3851
} catch (e: InvocationTargetException) {

0 commit comments

Comments
 (0)