Browse Source

Revert query modification in json parsing tests.

Add tests and move json string treatment into the ParameterBindingDocumentCodec.
Finally add issue references and format code.

Original Pull Request: #3907
pull/3950/head
Christoph Strobl 4 years ago
parent
commit
885d05965b
No known key found for this signature in database
GPG Key ID: 8CC1AB53391458C8
  1. 9
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingDocumentCodec.java
  2. 13
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReader.java
  3. 78
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReaderUnitTests.java

9
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingDocumentCodec.java

@ -217,8 +217,15 @@ public class ParameterBindingDocumentCodec implements CollectibleCodec<Document> @@ -217,8 +217,15 @@ public class ParameterBindingDocumentCodec implements CollectibleCodec<Document>
// binds just placeholder queries like: `@Query(?0)`
if (bindingReader.currentValue instanceof org.bson.Document) {
return (Document) bindingReader.currentValue;
} else if (bindingReader.currentValue instanceof String) {
try {
return decode((String) bindingReader.currentValue, new Object[0]);
} catch (JsonParseException jsonParseException) {
throw new IllegalArgumentException("Expression result is not a valid json document!", jsonParseException);
}
} else if (bindingReader.currentValue instanceof Map) {
return new Document((Map) bindingReader.currentValue);
}
}
Document document = new Document();

13
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReader.java

@ -36,7 +36,6 @@ import org.bson.types.Decimal128; @@ -36,7 +36,6 @@ import org.bson.types.Decimal128;
import org.bson.types.MaxKey;
import org.bson.types.MinKey;
import org.bson.types.ObjectId;
import org.springframework.data.spel.EvaluationContextProvider;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
@ -120,20 +119,8 @@ public class ParameterBindingJsonReader extends AbstractBsonReader { @@ -120,20 +119,8 @@ public class ParameterBindingJsonReader extends AbstractBsonReader {
Matcher matcher = ENTIRE_QUERY_BINDING_PATTERN.matcher(json);
if (matcher.find()) {
BindableValue bindingResult = bindableValueFor(new JsonToken(JsonTokenType.UNQUOTED_STRING, json));
try {
if (bindingResult.getValue() instanceof String) {
currentValue = Document.parse((String)bindingResult.getValue());
} else {
currentValue = bindingResult.getValue();
}
} catch (JsonParseException jsonParseException) {
throw new IllegalArgumentException(
String.format("Resulting value of expression '%s' is not a valid json query", json), jsonParseException);
}
}
}
// Spring Data Customization END

78
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/util/json/ParameterBindingJsonReaderUnitTests.java

@ -26,6 +26,7 @@ import java.util.Collections; @@ -26,6 +26,7 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.bson.BsonBinary;
import org.bson.Document;
import org.bson.codecs.DecoderContext;
import org.junit.jupiter.api.Test;
@ -347,7 +348,7 @@ class ParameterBindingJsonReaderUnitTests { @@ -347,7 +348,7 @@ class ParameterBindingJsonReaderUnitTests {
evaluationContext.setRootObject(new DummySecurityObject(new DummyWithId("wonderwoman")));
String json = "?#{ T(" + this.getClass().getName()
+ ").isBatman() ? \"{'_class': { '$eq' : 'region' }}\" : \"{ '$and' : [ {'_class': { '$eq' : 'region' } }, {'user.supervisor': '\"+ principal.id +\"' } ] }\" }";
+ ").isBatman() ? {'_class': { '$eq' : 'region' }} : { '$and' : { {'_class': { '$eq' : 'region' } }, {'user.supervisor': principal.id } } } }";
ParameterBindingJsonReader reader = new ParameterBindingJsonReader(json,
new ParameterBindingContext((index) -> args[index], new SpelExpressionParser(), evaluationContext));
@ -358,10 +359,65 @@ class ParameterBindingJsonReaderUnitTests { @@ -358,10 +359,65 @@ class ParameterBindingJsonReaderUnitTests {
new Document("user.supervisor", "wonderwoman"))));
}
@Test
@Test // GH-3871
public void capturingExpressionDependenciesShouldNotThrowParseErrorForSpelOnlyJson() {
Object[] args = new Object[] { "1", "2" };
String json = "?#{ true ? { 'name': #name } : { 'name' : #name + 'trouble' } }";
new ParameterBindingDocumentCodec().captureExpressionDependencies(json, (index) -> args[index],
new SpelExpressionParser());
}
@Test // GH-3871
public void bindEntireQueryUsingSpelExpressionWhenEvaluationResultIsJsonString() {
Object[] args = new Object[] { "expected", "unexpected" };
String json = "?#{ true ? \"{ 'name': ?0 }\" : \"{ 'name' : ?1 }\" }";
StandardEvaluationContext evaluationContext = (StandardEvaluationContext) EvaluationContextProvider.DEFAULT
.getEvaluationContext(args);
ParameterBindingJsonReader reader = new ParameterBindingJsonReader(json,
new ParameterBindingContext((index) -> args[index], new SpelExpressionParser(), evaluationContext));
Document target = new ParameterBindingDocumentCodec().decode(reader, DecoderContext.builder().build());
assertThat(target).isEqualTo(new Document("name", "expected"));
}
@Test // GH-3871
public void throwsExceptionWhenbindEntireQueryUsingSpelExpressionResultsInInvalidJsonString() {
Object[] args = new Object[] { "expected", "unexpected" };
String json = "?#{ true ? \"{ 'name': ?0 { }\" : \"{ 'name' : ?1 }\" }";
StandardEvaluationContext evaluationContext = (StandardEvaluationContext) EvaluationContextProvider.DEFAULT
.getEvaluationContext(args);
ParameterBindingJsonReader reader = new ParameterBindingJsonReader(json,
new ParameterBindingContext((index) -> args[index], new SpelExpressionParser(), evaluationContext));
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> new ParameterBindingDocumentCodec().decode(reader, DecoderContext.builder().build()));
}
@Test // GH-3871
public void bindEntireQueryUsingSpelExpressionWhenEvaluationResultIsJsonStringContainingUUID() {
Object[] args = new Object[] { "UUID('cfbca728-4e39-4613-96bc-f920b5c37e16')", "unexpected" };
String json = "?#{ true ? \"{ 'name': ?0 }\" : \"{ 'name' : ?1 }\" }";
StandardEvaluationContext evaluationContext = (StandardEvaluationContext) EvaluationContextProvider.DEFAULT
.getEvaluationContext(args);
ParameterBindingJsonReader reader = new ParameterBindingJsonReader(json,
new ParameterBindingContext((index) -> args[index], new SpelExpressionParser(), evaluationContext));
Document target = new ParameterBindingDocumentCodec().decode(reader, DecoderContext.builder().build());
assertThat(target.get("name")).isInstanceOf(BsonBinary.class);
}
@Test // GH-3871
void bindEntireQueryUsingSpelExpression() {
Object[] args = new Object[] {"region"};
Object[] args = new Object[] { "region" };
StandardEvaluationContext evaluationContext = (StandardEvaluationContext) EvaluationContextProvider.DEFAULT
.getEvaluationContext(args);
evaluationContext.setRootObject(new DummySecurityObject(new DummyWithId("wonderwoman")));
@ -377,10 +433,10 @@ class ParameterBindingJsonReaderUnitTests { @@ -377,10 +433,10 @@ class ParameterBindingJsonReaderUnitTests {
new Document("user.supervisor", "wonderwoman"))));
}
@Test
@Test // GH-3871
void bindEntireQueryUsingParameter() {
Object[] args = new Object[] {"{ 'itWorks' : true }"};
Object[] args = new Object[] { "{ 'itWorks' : true }" };
StandardEvaluationContext evaluationContext = (StandardEvaluationContext) EvaluationContextProvider.DEFAULT
.getEvaluationContext(args);
@ -390,9 +446,7 @@ class ParameterBindingJsonReaderUnitTests { @@ -390,9 +446,7 @@ class ParameterBindingJsonReaderUnitTests {
new ParameterBindingContext((index) -> args[index], new SpelExpressionParser(), evaluationContext));
Document target = new ParameterBindingDocumentCodec().decode(reader, DecoderContext.builder().build());
assertThat(target)
.isEqualTo(new Document("itWorks", true));
assertThat(target).isEqualTo(new Document("itWorks", true));
}
@Test // DATAMONGO-2571
@ -441,13 +495,9 @@ class ParameterBindingJsonReaderUnitTests { @@ -441,13 +495,9 @@ class ParameterBindingJsonReaderUnitTests {
public static String applyFilterByUser(String _class, String username) {
switch (username) {
case "batman":
return "{'_class': { '$eq' : '"
+ _class
+ "' }}";
return "{'_class': { '$eq' : '" + _class + "' }}";
default:
return "{ '$and' : [ {'_class': { '$eq' : '"
+ _class
+ "' } }, {'user.supervisor': '" + username + "' } ] }";
return "{ '$and' : [ {'_class': { '$eq' : '" + _class + "' } }, {'user.supervisor': '" + username + "' } ] }";
}
}

Loading…
Cancel
Save