Consider optional empty arrays to be absent when finding missing fields

Closes gh-519
This commit is contained in:
Andy Wilkinson
2018-06-25 16:59:19 +01:00
parent 7e49a20cb0
commit 7476562d22
2 changed files with 31 additions and 3 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2017 the original author or authors. * Copyright 2014-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package org.springframework.restdocs.payload;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -25,6 +26,8 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.restdocs.payload.JsonFieldProcessor.ExtractedField;
/** /**
* A {@link ContentHandler} for JSON content. * A {@link ContentHandler} for JSON content.
* *
@@ -70,13 +73,28 @@ class JsonContentHandler implements ContentHandler {
for (FieldDescriptor candidate : candidates) { for (FieldDescriptor candidate : candidates) {
if (candidate.isOptional() if (candidate.isOptional()
&& missing.getPath().startsWith(candidate.getPath()) && missing.getPath().startsWith(candidate.getPath())
&& !this.fieldProcessor.hasField(candidate.getPath(), payload)) { && isMissing(candidate, payload)) {
return true; return true;
} }
} }
return false; return false;
} }
private boolean isMissing(FieldDescriptor candidate, Object payload) {
try {
ExtractedField extracted = this.fieldProcessor.extract(candidate.getPath(),
payload);
if (extracted.getValue() instanceof Collection
&& ((Collection<?>) extracted.getValue()).isEmpty()) {
return true;
}
return false;
}
catch (FieldDoesNotExistException ex) {
return true;
}
}
@Override @Override
public String getUndocumentedContent(List<FieldDescriptor> fieldDescriptors) { public String getUndocumentedContent(List<FieldDescriptor> fieldDescriptors) {
Object content = readContent(); Object content = readContent();

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2017 the original author or authors. * Copyright 2014-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -147,4 +147,14 @@ public class JsonContentHandlerTests {
assertThat(missingFields.size(), is(equalTo(0))); assertThat(missingFields.size(), is(equalTo(0)));
} }
@Test
public void describedFieldThatIsNotPresentNestedBeneathOptionalArrayThatIsEmptyIsNotConsideredMissing() {
List<FieldDescriptor> missingFields = new JsonContentHandler(
"{\"outer\":[]}".getBytes())
.findMissingFields(Arrays.asList(new FieldDescriptor("outer"),
new FieldDescriptor("outer[]").optional(),
new FieldDescriptor("outer[].inner")));
assertThat(missingFields.size(), is(equalTo(0)));
}
} }