Skip to content
This repository was archived by the owner on Dec 19, 2023. It is now read-only.

Commit 60d1556

Browse files
authored
support for missing HandlerMethod (#152)
1 parent 201db70 commit 60d1556

File tree

14 files changed

+163
-30
lines changed

14 files changed

+163
-30
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@
229229
<dependency>
230230
<groupId>org.springframework</groupId>
231231
<artifactId>spring-test</artifactId>
232-
<version>4.3.6.RELEASE</version>
232+
<version>4.3.10.RELEASE</version>
233233
<scope>provided</scope>
234234
</dependency>
235235
<dependency>

spring-auto-restdocs-core/src/main/java/capital/scalable/restdocs/jackson/JacksonResultHandlers.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ public JacksonPreparingResultHandler(ObjectMapper objectMapper) {
4545

4646
@Override
4747
public void handle(MvcResult result) throws Exception {
48-
setHandlerMethod(result.getRequest(), (HandlerMethod) result.getHandler());
48+
// HandlerMethod is not present in case of invalid endpoint
49+
// or in case of static resource url
50+
if (result.getHandler() instanceof HandlerMethod) {
51+
setHandlerMethod(result.getRequest(), (HandlerMethod) result.getHandler());
52+
}
4953
setObjectMapper(result.getRequest(), objectMapper);
5054
initRequestPattern(result.getRequest());
5155
setJavadocReader(result.getRequest(), JavadocReaderImpl.createWithSystemProperty());

spring-auto-restdocs-core/src/main/java/capital/scalable/restdocs/misc/DescriptionSnippet.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,25 @@ public DescriptionSnippet() {
4040
@Override
4141
protected Map<String, Object> createModel(Operation operation) {
4242
HandlerMethod handlerMethod = getHandlerMethod(operation);
43+
Map<String, Object> model = defaultModel();
44+
if (handlerMethod == null) {
45+
return model;
46+
}
47+
4348
JavadocReader javadocReader = getJavadocReader(operation);
4449

4550
String methodComment = javadocReader.resolveMethodComment(handlerMethod.getBeanType(),
4651
handlerMethod.getMethod().getName());
4752

4853
methodComment = convertFromJavadoc(methodComment, determineForcedLineBreak(operation));
4954

50-
Map<String, Object> model = new HashMap<>();
5155
model.put("description", methodComment);
5256
return model;
5357
}
58+
59+
private Map<String, Object> defaultModel() {
60+
Map<String, Object> model = new HashMap<>();
61+
model.put("description", "");
62+
return model;
63+
}
5464
}

spring-auto-restdocs-core/src/main/java/capital/scalable/restdocs/section/SectionSnippet.java

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static capital.scalable.restdocs.OperationAttributeHelper.getDocumentationContext;
2121
import static capital.scalable.restdocs.OperationAttributeHelper.getHandlerMethod;
2222
import static capital.scalable.restdocs.OperationAttributeHelper.getJavadocReader;
23+
import static java.util.Collections.emptyList;
2324
import static org.apache.commons.lang3.StringUtils.join;
2425
import static org.apache.commons.lang3.StringUtils.splitByCharacterTypeCamelCase;
2526
import static org.slf4j.LoggerFactory.getLogger;
@@ -64,22 +65,26 @@ public SectionSnippet(Collection<String> sectionNames, boolean skipEmpty) {
6465

6566
@Override
6667
protected Map<String, Object> createModel(Operation operation) {
68+
Map<String, Object> model = defaultModel(operation);
69+
6770
HandlerMethod handlerMethod = getHandlerMethod(operation);
68-
JavadocReader javadocReader = getJavadocReader(operation);
71+
if (handlerMethod == null) {
72+
return model;
73+
}
6974

75+
JavadocReader javadocReader = getJavadocReader(operation);
7076
String title = resolveTitle(handlerMethod, javadocReader);
7177

72-
// resolve path
73-
String path = propertyPlaceholderHelper.replacePlaceholders(operation.getName(),
74-
placeholderResolverFactory.create(getDocumentationContext(operation)));
75-
76-
Map<String, Object> model = new HashMap<>();
7778
model.put("title", title);
78-
model.put("link", delimit(path));
79-
model.put("path", path);
80-
List<SectionSupport> sections = new ArrayList<>();
81-
model.put("sections", sections);
79+
model.put("sections", createSections(operation));
80+
81+
createSections(operation);
8282

83+
return model;
84+
}
85+
86+
private List<SectionSupport> createSections(Operation operation) {
87+
List<SectionSupport> sections = new ArrayList<>();
8388
for (String sectionName : sectionNames) {
8489
SectionSupport section = getSectionSnippet(operation, sectionName);
8590
if (section != null) {
@@ -91,20 +96,35 @@ protected Map<String, Object> createModel(Operation operation) {
9196
"included in the section but no such snippet is present in configuration");
9297
}
9398
}
99+
return sections;
100+
}
94101

102+
private Map<String, Object> defaultModel(Operation operation) {
103+
// resolve path
104+
String path = propertyPlaceholderHelper.replacePlaceholders(operation.getName(),
105+
placeholderResolverFactory.create(getDocumentationContext(operation)));
106+
107+
Map<String, Object> model = new HashMap<>();
108+
model.put("title", createTitle(operation.getName()));
109+
model.put("link", delimit(path));
110+
model.put("path", path);
111+
model.put("sections", emptyList());
95112
return model;
96113
}
97114

98115
private String resolveTitle(HandlerMethod handlerMethod, JavadocReader javadocReader) {
99116
String title = javadocReader.resolveMethodTitle(handlerMethod.getBeanType(),
100117
handlerMethod.getMethod().getName());
101118
if (StringUtils.isBlank(title)) {
102-
title = join(splitByCharacterTypeCamelCase(
103-
capitalize(handlerMethod.getMethod().getName())), ' ');
119+
title = createTitle(handlerMethod.getMethod().getName());
104120
}
105121
return title;
106122
}
107123

124+
private String createTitle(String name) {
125+
return join(splitByCharacterTypeCamelCase(capitalize(name)), ' ');
126+
}
127+
108128
private SectionSupport getSectionSnippet(Operation operation, String snippetName) {
109129
for (Snippet snippet : getDefaultSnippets(operation)) {
110130
if (snippet instanceof SectionSupport) {

spring-auto-restdocs-core/src/main/java/capital/scalable/restdocs/snippet/StandardTableSnippet.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,17 @@ protected StandardTableSnippet(String snippetName, Map<String, Object> attribute
4545
@Override
4646
protected Map<String, Object> createModel(Operation operation) {
4747
HandlerMethod handlerMethod = getHandlerMethod(operation);
48+
Map<String, Object> model = defaultModel();
49+
if (handlerMethod == null) {
50+
return model;
51+
}
52+
4853
Collection<FieldDescriptor> fieldDescriptors = emptyList();
49-
fieldDescriptors = createFieldDescriptors(operation, handlerMethod);
54+
fieldDescriptors = createFieldDescriptors(operation, handlerMethod);
5055

5156
String forcedLineBreak = determineForcedLineBreak(operation);
5257

53-
return createModel(handlerMethod, fieldDescriptors, forcedLineBreak);
58+
return createModel(handlerMethod, model, fieldDescriptors, forcedLineBreak);
5459
}
5560

5661
protected abstract Collection<FieldDescriptor> createFieldDescriptors(Operation operation,
@@ -60,10 +65,8 @@ protected void enrichModel(Map<String, Object> model, HandlerMethod handlerMetho
6065
// can be used to add additional fields
6166
}
6267

63-
private Map<String, Object> createModel(HandlerMethod handlerMethod,
68+
private Map<String, Object> createModel(HandlerMethod handlerMethod, Map<String, Object> model,
6469
Collection<FieldDescriptor> fieldDescriptors, String forcedLineBreak) {
65-
Map<String, Object> model = new HashMap<>();
66-
6770
List<Map<String, Object>> fields = new ArrayList<>();
6871
model.put("content", fields);
6972
for (FieldDescriptor descriptor : fieldDescriptors) {
@@ -77,6 +80,14 @@ private Map<String, Object> createModel(HandlerMethod handlerMethod,
7780
return model;
7881
}
7982

83+
private Map<String, Object> defaultModel() {
84+
Map<String, Object> model = new HashMap<>();
85+
model.put("content", "");
86+
model.put("hasContent", false);
87+
model.put("noContent", true);
88+
return model;
89+
}
90+
8091
protected Map<String, Object> createModelForDescriptor(FieldDescriptor descriptor,
8192
String forcedLineBreak) {
8293
String path = descriptor.getPath();

spring-auto-restdocs-core/src/test/java/capital/scalable/restdocs/misc/DescriptionSnippetTest.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,12 @@ public DescriptionSnippetTest(String name, TemplateFormat templateFormat) {
3535

3636
@Test
3737
public void description() throws Exception {
38-
HandlerMethod handlerMethod = new HandlerMethod(new TestResource(),
39-
"testDescription");
38+
HandlerMethod handlerMethod = new HandlerMethod(new TestResource(), "testDescription");
4039
JavadocReader javadocReader = mock(JavadocReader.class);
4140
when(javadocReader.resolveMethodComment(TestResource.class, "testDescription"))
4241
.thenReturn("Sample method comment");
4342

44-
this.snippets.expect(DESCRIPTION)
45-
.withContents(equalTo("Sample method comment"));
43+
this.snippets.expect(DESCRIPTION).withContents(equalTo("Sample method comment"));
4644

4745
new DescriptionSnippet().document(operationBuilder
4846
.attribute(HandlerMethod.class.getName(), handlerMethod)
@@ -51,6 +49,15 @@ public void description() throws Exception {
5149
.build());
5250
}
5351

52+
@Test
53+
public void noHandlerMethod() throws Exception {
54+
this.snippets.expect(DESCRIPTION).withContents(equalTo(""));
55+
56+
new DescriptionSnippet().document(operationBuilder
57+
.request("http://localhost/test")
58+
.build());
59+
}
60+
5461
private static class TestResource {
5562

5663
public void testDescription() {

spring-auto-restdocs-core/src/test/java/capital/scalable/restdocs/misc/MethodAndPathSnippetTest.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ public MethodAndPathSnippetTest(String name, TemplateFormat templateFormat) {
3535
public void simpleRequest() throws Exception {
3636
HandlerMethod handlerMethod = new HandlerMethod(new TestResource(), "testMethod");
3737

38-
this.snippets.expect(METHOD_PATH)
39-
.withContents(equalTo("`POST /test`"));
38+
this.snippets.expect(METHOD_PATH).withContents(equalTo("`POST /test`"));
4039

4140
new MethodAndPathSnippet().document(operationBuilder
4241
.attribute(HandlerMethod.class.getName(), handlerMethod)
@@ -46,6 +45,17 @@ public void simpleRequest() throws Exception {
4645
.build());
4746
}
4847

48+
@Test
49+
public void noHandlerMethod() throws Exception {
50+
this.snippets.expect(METHOD_PATH).withContents(equalTo("`POST /test`"));
51+
52+
new MethodAndPathSnippet().document(operationBuilder
53+
.attribute(REQUEST_PATTERN, "/test")
54+
.request("http://localhost/test")
55+
.method("POST")
56+
.build());
57+
}
58+
4959
private static class TestResource {
5060

5161
public void testMethod() {

spring-auto-restdocs-core/src/test/java/capital/scalable/restdocs/payload/JacksonRequestFieldSnippetTest.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,15 @@ public void noRequestBody() throws Exception {
101101
.build());
102102
}
103103

104+
@Test
105+
public void noHandlerMethod() throws Exception {
106+
this.snippets.expect(REQUEST_FIELDS).withContents(equalTo("No request body."));
107+
108+
new JacksonRequestFieldSnippet().document(operationBuilder
109+
.attribute(ObjectMapper.class.getName(), mapper)
110+
.build());
111+
}
112+
104113
@Test
105114
public void listRequest() throws Exception {
106115
HandlerMethod handlerMethod = createHandlerMethod("addItems", List.class);
@@ -206,7 +215,6 @@ public void failOnUndocumentedFields() throws Exception {
206215
.build());
207216
}
208217

209-
210218
private void mockConstraintMessage(Class<?> type, String fieldName, String comment) {
211219
when(constraintReader.getConstraintMessages(type, fieldName))
212220
.thenReturn(singletonList(comment));

spring-auto-restdocs-core/src/test/java/capital/scalable/restdocs/payload/JacksonResponseFieldSnippetTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,15 @@ public void noResponseBody() throws Exception {
123123
.build());
124124
}
125125

126+
@Test
127+
public void noHandlerMethod() throws Exception {
128+
this.snippets.expect(RESPONSE_FIELDS).withContents(equalTo("No response body."));
129+
130+
new JacksonResponseFieldSnippet().document(operationBuilder
131+
.attribute(ObjectMapper.class.getName(), mapper)
132+
.build());
133+
}
134+
126135
@Test
127136
public void pageResponse() throws Exception {
128137
HandlerMethod handlerMethod = createHandlerMethod("pagedItems");

spring-auto-restdocs-core/src/test/java/capital/scalable/restdocs/request/PathParametersSnippetTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ public void noParameters() throws Exception {
8888
.build());
8989
}
9090

91+
@Test
92+
public void noHandlerMethod() throws Exception {
93+
this.snippets.expect(PATH_PARAMETERS).withContents(equalTo("No parameters."));
94+
95+
new PathParametersSnippet().document(operationBuilder
96+
.build());
97+
}
98+
9199
@Test
92100
public void failOnUndocumentedParams() throws Exception {
93101
HandlerMethod handlerMethod = createHandlerMethod("addItem", Integer.class, String.class,

0 commit comments

Comments
 (0)