DATACOUCH-561 - Better Testing for String Query
This commit is contained in:
@@ -31,6 +31,7 @@ public class Airline {
|
||||
@PersistenceConstructor
|
||||
public Airline(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
@@ -41,4 +42,15 @@ public class Airline {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
StringBuilder sb=new StringBuilder();
|
||||
sb.append("airline: { ");
|
||||
sb.append(" id: ");
|
||||
sb.append(id);
|
||||
sb.append(" , name: ");
|
||||
sb.append(name);
|
||||
sb.append(" }");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,17 @@
|
||||
|
||||
package org.springframework.data.couchbase.domain;
|
||||
|
||||
import org.springframework.data.couchbase.repository.Query;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface AirlineRepository extends PagingAndSortingRepository<Airline, String> {
|
||||
|
||||
@Query("#{#n1ql.selectEntity} where (name = $1)")
|
||||
List<User> getByName(@Param("airline_name")String airlineName);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright 2017-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.couchbase.repository.query;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.data.couchbase.core.ExecutableFindByQueryOperation;
|
||||
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.couchbase.domain.Airline;
|
||||
import org.springframework.data.couchbase.domain.AirlineRepository;
|
||||
import org.springframework.data.couchbase.domain.User;
|
||||
import org.springframework.data.couchbase.domain.UserRepository;
|
||||
import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;
|
||||
import org.springframework.data.couchbase.util.Capabilities;
|
||||
import org.springframework.data.couchbase.util.ClusterAwareIntegrationTests;
|
||||
import org.springframework.data.couchbase.util.ClusterType;
|
||||
import org.springframework.data.couchbase.util.IgnoreWhen;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
||||
import org.springframework.data.repository.core.support.PropertiesBasedNamedQueries;
|
||||
import org.springframework.data.repository.query.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.springframework.data.couchbase.config.BeanNames.COUCHBASE_TEMPLATE;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
@IgnoreWhen(clusterTypes = ClusterType.UNMANAGED)
|
||||
class StringN1qlQueryCreatorMockedTests extends ClusterAwareIntegrationTests {
|
||||
|
||||
MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> context;
|
||||
CouchbaseConverter converter;
|
||||
CouchbaseTemplate couchbaseTemplate;
|
||||
static NamedQueries namedQueries = new PropertiesBasedNamedQueries(new Properties());
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() {
|
||||
context = new CouchbaseMappingContext();
|
||||
converter = new MappingCouchbaseConverter(context);
|
||||
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
|
||||
couchbaseTemplate = (CouchbaseTemplate) ac.getBean(COUCHBASE_TEMPLATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createsQueryCorrectly() throws Exception {
|
||||
String input = "getByFirstnameAndLastname";
|
||||
Method method = UserRepository.class.getMethod(input, String.class, String.class);
|
||||
|
||||
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method,
|
||||
new DefaultRepositoryMetadata(UserRepository.class), new SpelAwareProxyProjectionFactory(),
|
||||
converter.getMappingContext());
|
||||
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(
|
||||
getAccessor(getParameters(method), "Oliver", "Twist"), queryMethod, converter, "travel-sample",
|
||||
QueryMethodEvaluationContextProvider.DEFAULT, namedQueries);
|
||||
|
||||
Query query = creator.createQuery();
|
||||
assertEquals(
|
||||
"SELECT META(`travel-sample`).id AS __id, META(`travel-sample`).cas AS __cas, `travel-sample`.* FROM `travel-sample` where firstname = $1 and lastname = $2 AND `_class` = \"org.springframework.data.couchbase.domain.User\"",
|
||||
query.toN1qlString(couchbaseTemplate.reactive(), User.class, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void createsQueryCorrectly2() throws Exception {
|
||||
String input = "getByFirstnameOrLastname";
|
||||
Method method = UserRepository.class.getMethod(input, String.class, String.class);
|
||||
|
||||
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method,
|
||||
new DefaultRepositoryMetadata(UserRepository.class), new SpelAwareProxyProjectionFactory(),
|
||||
converter.getMappingContext());
|
||||
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(
|
||||
getAccessor(getParameters(method), "Oliver", "Twist"), queryMethod, converter, "travel-sample",
|
||||
QueryMethodEvaluationContextProvider.DEFAULT, namedQueries);
|
||||
|
||||
Query query = creator.createQuery();
|
||||
assertEquals(
|
||||
"SELECT META(`travel-sample`).id AS __id, META(`travel-sample`).cas AS __cas, `travel-sample`.* FROM `travel-sample` where (firstname = $first or lastname = $last) AND `_class` = \"org.springframework.data.couchbase.domain.User\"",
|
||||
query.toN1qlString(couchbaseTemplate.reactive(), User.class, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void wrongNumberArgs() throws Exception {
|
||||
String input = "getByFirstnameOrLastname";
|
||||
Method method = UserRepository.class.getMethod(input, String.class, String.class);
|
||||
|
||||
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method,
|
||||
new DefaultRepositoryMetadata(UserRepository.class), new SpelAwareProxyProjectionFactory(),
|
||||
converter.getMappingContext());
|
||||
|
||||
try {
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver"),
|
||||
queryMethod, converter, "travel-sample", QueryMethodEvaluationContextProvider.DEFAULT,
|
||||
namedQueries);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return;
|
||||
}
|
||||
fail("should have failed with IllegalArgumentException: Invalid number of parameters given!");
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotHaveAnnotation() throws Exception {
|
||||
String input = "findByFirstname";
|
||||
Method method = UserRepository.class.getMethod(input, String.class);
|
||||
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method,
|
||||
new DefaultRepositoryMetadata(UserRepository.class), new SpelAwareProxyProjectionFactory(),
|
||||
converter.getMappingContext());
|
||||
|
||||
try {
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver"),
|
||||
queryMethod, converter, "travel-sample", QueryMethodEvaluationContextProvider.DEFAULT,
|
||||
namedQueries);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return;
|
||||
}
|
||||
fail("should have failed with IllegalArgumentException: query has no inline Query or named Query not found");
|
||||
}
|
||||
|
||||
|
||||
private ParameterAccessor getAccessor(Parameters<?, ?> params, Object... values) {
|
||||
return new ParametersParameterAccessor(params, values);
|
||||
}
|
||||
|
||||
private Parameters<?, ?> getParameters(Method method) {
|
||||
return new DefaultParameters(method);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableCouchbaseRepositories("org.springframework.data.couchbase")
|
||||
static class Config extends AbstractCouchbaseConfiguration {
|
||||
|
||||
@Override
|
||||
public String getConnectionString() {
|
||||
return connectionString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserName() {
|
||||
return config().adminUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return config().adminPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBucketName() {
|
||||
return bucketName();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -19,13 +19,17 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.springframework.data.couchbase.config.BeanNames.COUCHBASE_TEMPLATE;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.data.couchbase.core.ExecutableFindByQueryOperation;
|
||||
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
|
||||
@@ -34,10 +38,10 @@ import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
|
||||
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
|
||||
import org.springframework.data.couchbase.core.query.Query;
|
||||
import org.springframework.data.couchbase.domain.Config;
|
||||
import org.springframework.data.couchbase.domain.User;
|
||||
import org.springframework.data.couchbase.domain.UserRepository;
|
||||
import org.springframework.data.couchbase.domain.*;
|
||||
import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;
|
||||
import org.springframework.data.couchbase.util.Capabilities;
|
||||
import org.springframework.data.couchbase.util.ClusterAwareIntegrationTests;
|
||||
import org.springframework.data.couchbase.util.ClusterType;
|
||||
import org.springframework.data.couchbase.util.IgnoreWhen;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
@@ -46,20 +50,22 @@ import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
||||
import org.springframework.data.repository.core.support.PropertiesBasedNamedQueries;
|
||||
import org.springframework.data.repository.query.*;
|
||||
|
||||
import javax.el.MethodNotFoundException;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
class StringN1qlQueryCreatorTests {
|
||||
@SpringJUnitConfig(StringN1qlQueryCreatorTests.Config.class)
|
||||
@IgnoreWhen(clusterTypes = ClusterType.MOCKED)
|
||||
class StringN1qlQueryCreatorTests extends ClusterAwareIntegrationTests {
|
||||
|
||||
MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> context;
|
||||
CouchbaseConverter converter;
|
||||
CouchbaseTemplate couchbaseTemplate;
|
||||
static NamedQueries namedQueries = new PropertiesBasedNamedQueries(new Properties());
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() {
|
||||
context = new CouchbaseMappingContext();
|
||||
@@ -68,107 +74,41 @@ class StringN1qlQueryCreatorTests {
|
||||
couchbaseTemplate = (CouchbaseTemplate) ac.getBean(COUCHBASE_TEMPLATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createsQueryCorrectly() throws Exception {
|
||||
String input = "getByFirstnameAndLastname";
|
||||
Method method = UserRepository.class.getMethod(input, String.class, String.class);
|
||||
|
||||
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method,
|
||||
new DefaultRepositoryMetadata(UserRepository.class), new SpelAwareProxyProjectionFactory(),
|
||||
converter.getMappingContext());
|
||||
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(
|
||||
getAccessor(getParameters(method), "Oliver", "Twist"), queryMethod, converter, "travel-sample",
|
||||
QueryMethodEvaluationContextProvider.DEFAULT, namedQueries);
|
||||
|
||||
Query query = creator.createQuery();
|
||||
assertEquals(
|
||||
"SELECT META(`travel-sample`).id AS __id, META(`travel-sample`).cas AS __cas, `travel-sample`.* FROM `travel-sample` where firstname = $1 and lastname = $2 AND `_class` = \"org.springframework.data.couchbase.domain.User\"",
|
||||
query.toN1qlString(couchbaseTemplate.reactive(), User.class, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void createsQueryCorrectly2() throws Exception {
|
||||
String input = "getByFirstnameOrLastname";
|
||||
Method method = UserRepository.class.getMethod(input, String.class, String.class);
|
||||
|
||||
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method,
|
||||
new DefaultRepositoryMetadata(UserRepository.class), new SpelAwareProxyProjectionFactory(),
|
||||
converter.getMappingContext());
|
||||
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(
|
||||
getAccessor(getParameters(method), "Oliver", "Twist"), queryMethod, converter, "travel-sample",
|
||||
QueryMethodEvaluationContextProvider.DEFAULT, namedQueries);
|
||||
|
||||
Query query = creator.createQuery();
|
||||
assertEquals(
|
||||
"SELECT META(`travel-sample`).id AS __id, META(`travel-sample`).cas AS __cas, `travel-sample`.* FROM `travel-sample` where (firstname = $first or lastname = $last) AND `_class` = \"org.springframework.data.couchbase.domain.User\"",
|
||||
query.toN1qlString(couchbaseTemplate.reactive(), User.class, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void wrongNumberArgs() throws Exception {
|
||||
String input = "getByFirstnameOrLastname";
|
||||
Method method = UserRepository.class.getMethod(input, String.class, String.class);
|
||||
|
||||
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method,
|
||||
new DefaultRepositoryMetadata(UserRepository.class), new SpelAwareProxyProjectionFactory(),
|
||||
converter.getMappingContext());
|
||||
|
||||
try {
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver"),
|
||||
queryMethod, converter, "travel-sample", QueryMethodEvaluationContextProvider.DEFAULT,
|
||||
namedQueries);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return;
|
||||
}
|
||||
fail("should have failed with IllegalArgumentException: Invalid number of parameters given!");
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotHaveAnnotation() throws Exception {
|
||||
String input = "findByFirstname";
|
||||
Method method = UserRepository.class.getMethod(input, String.class);
|
||||
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method,
|
||||
new DefaultRepositoryMetadata(UserRepository.class), new SpelAwareProxyProjectionFactory(),
|
||||
converter.getMappingContext());
|
||||
|
||||
try {
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver"),
|
||||
queryMethod, converter, "travel-sample", QueryMethodEvaluationContextProvider.DEFAULT,
|
||||
namedQueries);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return;
|
||||
}
|
||||
fail("should have failed with IllegalArgumentException: query has no inline Query or named Query not found");
|
||||
}
|
||||
|
||||
@Test
|
||||
@IgnoreWhen(missesCapabilities = Capabilities.QUERY, clusterTypes = ClusterType.MOCKED)
|
||||
void findUsingStringNq1l() throws Exception {
|
||||
User user = new User(UUID.randomUUID().toString(), "Oliver", "Twist");
|
||||
User modified = couchbaseTemplate.upsertById(User.class).one(user);
|
||||
Airline airline = new Airline(UUID.randomUUID().toString(), "Continental");
|
||||
try {
|
||||
Airline modified = couchbaseTemplate.upsertById(Airline.class).one(airline);
|
||||
|
||||
String input = "getByFirstnameOrLastname";
|
||||
Method method = UserRepository.class.getMethod(input, String.class, String.class);
|
||||
String input = "getByName";
|
||||
Method method = AirlineRepository.class.getMethod(input, String.class);
|
||||
|
||||
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method,
|
||||
new DefaultRepositoryMetadata(UserRepository.class), new SpelAwareProxyProjectionFactory(),
|
||||
converter.getMappingContext());
|
||||
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method,
|
||||
new DefaultRepositoryMetadata(UserRepository.class), new SpelAwareProxyProjectionFactory(),
|
||||
converter.getMappingContext());
|
||||
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(
|
||||
getAccessor(getParameters(method), "Oliver", "Twist"), queryMethod, converter, "travel-sample",
|
||||
QueryMethodEvaluationContextProvider.DEFAULT, namedQueries);
|
||||
|
||||
Query query = creator.createQuery();
|
||||
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(
|
||||
getAccessor(getParameters(method), "Continental"), queryMethod, converter, config().bucketname(),
|
||||
QueryMethodEvaluationContextProvider.DEFAULT, namedQueries);
|
||||
|
||||
ExecutableFindByQueryOperation.ExecutableFindByQuery q = (ExecutableFindByQueryOperation.ExecutableFindByQuery) couchbaseTemplate.findByQuery(
|
||||
User.class).matching(query);
|
||||
Query query = creator.createQuery();
|
||||
System.out.println(query.toN1qlString(couchbaseTemplate.reactive(), User.class, false));
|
||||
|
||||
User u = (User) q.oneValue();
|
||||
assertEquals(user, u);
|
||||
try { Thread.sleep(3000); } catch (Exception e){}
|
||||
ExecutableFindByQueryOperation.ExecutableFindByQuery q = (ExecutableFindByQueryOperation.ExecutableFindByQuery) couchbaseTemplate.findByQuery(
|
||||
Airline.class).matching(query);
|
||||
|
||||
couchbaseTemplate.removeById().one(user.getId());
|
||||
Optional<Airline> al = q.one();
|
||||
assertEquals(airline.toString(), al.get().toString());
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
couchbaseTemplate.removeById().one(airline.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private ParameterAccessor getAccessor(Parameters<?, ?> params, Object... values) {
|
||||
@@ -179,4 +119,34 @@ class StringN1qlQueryCreatorTests {
|
||||
return new DefaultParameters(method);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableCouchbaseRepositories("org.springframework.data.couchbase")
|
||||
static class Config extends AbstractCouchbaseConfiguration {
|
||||
|
||||
@Override
|
||||
public String getConnectionString() {
|
||||
return connectionString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserName() {
|
||||
return config().adminUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return config().adminPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBucketName() {
|
||||
return bucketName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean autoIndexCreation() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user