Skip to content

Commit 81b55d4

Browse files
committed
Refine missing field detection logic for paths with multiple arrays
Previously, missing field detection worked correctly for paths containing a single array, but if the path contained multiple arrays the extracted value would be a list containing a single empty list. In this case the field would not be considered missing when, in fact it should have been. This commit updates the missing field detection logic to recursively examine the extracted value and, when it's a collection, the values that it contains. As a result, a field will be considered to be missing if it isn't present, if it's an empty collection, or if it's a collection that only contains empty collections or, to any depth, collections of empty collections. Closes gh-519
1 parent 001fb38 commit 81b55d4

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,23 @@ private boolean isMissing(FieldDescriptor candidate, Object payload) {
8686
}
8787
ExtractedField extracted = this.fieldProcessor.extract(candidate.getPath(),
8888
payload);
89-
return extracted.getValue() instanceof Collection
90-
&& ((Collection<?>) extracted.getValue()).isEmpty();
89+
return isEmptyCollection(extracted.getValue());
90+
}
91+
92+
private boolean isEmptyCollection(Object value) {
93+
if (!(value instanceof Collection)) {
94+
return false;
95+
}
96+
Collection<?> collection = (Collection<?>) value;
97+
if (collection.isEmpty()) {
98+
return true;
99+
}
100+
for (Object entry : collection) {
101+
if (!isEmptyCollection(entry)) {
102+
return false;
103+
}
104+
}
105+
return true;
91106
}
92107

93108
@Override

spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public void describedFieldThatIsNotPresentNestedBeneathOptionalArrayThatIsEmptyI
158158
}
159159

160160
@Test
161-
public void describedFieldThatIsSometimesPresentChildOfOptionalArrayIsNotConsideredMissing() {
161+
public void describedSometimesPresentFieldThatIsChildOfSometimesPresentOptionalArrayIsNotConsideredMissing() {
162162
List<FieldDescriptor> missingFields = new JsonContentHandler(
163163
"{\"a\":[ {\"b\": \"bravo\"}, {\"b\": \"bravo\", \"c\": { \"d\": \"delta\"}}]}"
164164
.getBytes()).findMissingFields(
@@ -167,4 +167,25 @@ public void describedFieldThatIsSometimesPresentChildOfOptionalArrayIsNotConside
167167
assertThat(missingFields.size(), is(equalTo(0)));
168168
}
169169

170+
@Test
171+
public void describedMissingFieldThatIsChildOfNestedOptionalArrayThatIsEmptyIsNotConsideredMissing() {
172+
List<FieldDescriptor> missingFields = new JsonContentHandler(
173+
"{\"a\":[{\"b\":[]}]}".getBytes()).findMissingFields(
174+
Arrays.asList(new FieldDescriptor("a.[].b").optional(),
175+
new FieldDescriptor("a.[].b.[]").optional(),
176+
new FieldDescriptor("a.[].b.[].c")));
177+
assertThat(missingFields.size(), is(equalTo(0)));
178+
}
179+
180+
@Test
181+
public void describedMissingFieldThatIsChildOfNestedOptionalArrayThatContainsAnObjectIsConsideredMissing() {
182+
List<FieldDescriptor> missingFields = new JsonContentHandler(
183+
"{\"a\":[{\"b\":[{}]}]}".getBytes()).findMissingFields(
184+
Arrays.asList(new FieldDescriptor("a.[].b").optional(),
185+
new FieldDescriptor("a.[].b.[]").optional(),
186+
new FieldDescriptor("a.[].b.[].c")));
187+
assertThat(missingFields.size(), is(equalTo(1)));
188+
assertThat(missingFields.get(0).getPath(), is(equalTo("a.[].b.[].c")));
189+
}
190+
170191
}

0 commit comments

Comments
 (0)