Skip to content

Commit

Permalink
Support beneathPath in MockMvcRestDocumentationWrapper (#250)
Browse files Browse the repository at this point in the history
Co-authored-by: Phil Owen <phowen@cisco.com>
  • Loading branch information
philipowen and phowen-cisco authored Feb 13, 2024
1 parent c631886 commit fb47811
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.springframework.restdocs.hypermedia.HypermediaDocumentation.links
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post
import org.springframework.restdocs.operation.preprocess.OperationRequestPreprocessor
import org.springframework.restdocs.payload.PayloadDocumentation.beneathPath
import org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath
import org.springframework.restdocs.payload.PayloadDocumentation.requestFields
import org.springframework.restdocs.payload.PayloadDocumentation.responseFields
Expand Down Expand Up @@ -51,6 +52,15 @@ class MockMvcRestDocumentationWrapperIntegrationTest(@Autowired private val mock
thenSnippetFileExists()
}

@Test
fun should_document_both_restdocs_and_resource_with_path() {
givenEndpointInvoked()

whenDocumentedWithPayloadSubsectionExtractor()

thenSnippetFileExists()
}

@Test
fun should_document_using_the_passed_raml_snippet() {
givenEndpointInvoked()
Expand Down Expand Up @@ -250,6 +260,39 @@ class MockMvcRestDocumentationWrapperIntegrationTest(@Autowired private val mock
)
}

@Throws(Exception::class)
private fun whenDocumentedWithPayloadSubsectionExtractor() {
val operationRequestPreprocessor = OperationRequestPreprocessor { r -> r }
resultActions
.andDo(
MockMvcRestDocumentationWrapper.document(
identifier = operationName,
privateResource = true,
requestPreprocessor = operationRequestPreprocessor,
snippets = arrayOf(
requestFields(fieldDescriptors().fieldDescriptors),
responseFields(
fieldWithPath("comment").description("the comment"),
fieldWithPath("flag").description("the flag"),
fieldWithPath("count").description("the count"),
fieldWithPath("id").description("id"),
subsectionWithPath("_links").ignored()
),
responseFields(
beneathPath("_links").withSubsectionId("beneath-links"),
fieldWithPath("self").description("self link"),
fieldWithPath("self.href").description("self link href"),
subsectionWithPath("multiple").ignored(),
),
links(
linkWithRel("self").description("some"),
linkWithRel("multiple").description("multiple")
)
)
)
)
}

@Throws(Exception::class)
private fun whenDocumentedWithResourceSnippetDetails() {
val operationRequestPreprocessor = OperationRequestPreprocessor { r -> r }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import org.springframework.restdocs.hypermedia.LinkDescriptor
import org.springframework.restdocs.hypermedia.LinksSnippet
import org.springframework.restdocs.payload.AbstractFieldsSnippet
import org.springframework.restdocs.payload.FieldDescriptor
import org.springframework.restdocs.payload.FieldPathPayloadSubsectionExtractor
import org.springframework.restdocs.payload.PayloadDocumentation
import org.springframework.restdocs.payload.PayloadSubsectionExtractor
import org.springframework.restdocs.request.AbstractParametersSnippet
import org.springframework.restdocs.request.ParameterDescriptor
import org.springframework.restdocs.snippet.AbstractDescriptor
Expand All @@ -32,7 +35,17 @@ internal object DescriptorExtractor {
try {
val getFieldDescriptors = AbstractFieldsSnippet::class.java.getDeclaredMethod("getFieldDescriptors")
getFieldDescriptors.isAccessible = true
return getFieldDescriptors.invoke(snippet) as List<FieldDescriptor>
var descriptors = getFieldDescriptors.invoke(snippet) as List<FieldDescriptor>
val getSubsectionExtractor = AbstractFieldsSnippet::class.java.getDeclaredMethod("getSubsectionExtractor")
getSubsectionExtractor.isAccessible = true
val payloadSubsectionExtractor = getSubsectionExtractor.invoke(snippet) as PayloadSubsectionExtractor<*>?
if (payloadSubsectionExtractor is FieldPathPayloadSubsectionExtractor) {
val getFieldPath = FieldPathPayloadSubsectionExtractor::class.java.getDeclaredMethod("getFieldPath")
getFieldPath.isAccessible = true
val fieldPath = getFieldPath.invoke(payloadSubsectionExtractor) as String
descriptors = PayloadDocumentation.applyPathPrefix("$fieldPath.", descriptors)
}
return descriptors
} catch (e: NoSuchMethodException) {
e.printStackTrace()
} catch (e: InvocationTargetException) {
Expand Down

0 comments on commit fb47811

Please sign in to comment.