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
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
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);
|
||||
}
|
||||
currentValue = bindingResult.getValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Spring Data Customization END
|
||||
|
||||
@@ -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 {
|
||||
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));
|
||||
@@ -357,11 +358,66 @@ class ParameterBindingJsonReaderUnitTests {
|
||||
.isEqualTo(new Document("$and", Arrays.asList(new Document("_class", new Document("$eq", "region")),
|
||||
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 {
|
||||
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 {
|
||||
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
|
||||
@@ -437,17 +491,13 @@ class ParameterBindingJsonReaderUnitTests {
|
||||
public static boolean isBatman() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
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 + "' } ] }";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user