package org.springframework.data.simpledb.query;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.repository.query.Parameter;
import org.springframework.data.repository.query.Parameters;
import org.springframework.data.simpledb.attributeutil.SimpleDBAttributeConverter;
import org.springframework.data.simpledb.core.domain.SimpleDbSampleEntity;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
public class QueryUtilsNamedQueryTest {
@Test
public void buildQueryConditionsWithParameters_should_work_with_WHERE_clause() {
final String expectedQuery = "select * from spring_data where type = 'spring-type'";
final String rawQuery = "select * from spring_data where type = :type";
final Parameters parameters = getMockParameters(new String[]{":type"}, new Class[]{String.class});
String resultedQuery = QueryUtils.buildQuery(rawQuery, parameters, "spring-type");
assertThat(resultedQuery, is(expectedQuery));
}
@Test
public void buildQueryConditionsWithParameters_should_return_a_formatted_query() {
final String expectedQuery = "select * from spring_data where name = 'spring-name' and type = 'spring-type' or location = 'Timisoara'";
final String rawQuery = "select * from spring_data where name = :name and type = :type or location = :location ";
final Parameters parameters = getMockParameters(new String[]{":name", ":type", ":location"}, new Class[]{String.class, String.class, String.class});
String resultedQuery = QueryUtils.buildQuery(rawQuery, parameters, "spring-name",
"spring-type", "Timisoara");
assertThat(resultedQuery, is(expectedQuery));
}
@Test
public void buildQueryConditionsWithParameters_should_construct_correct_query_with_converted_parameter_values() {
final String bind_query = "select * from customer_all WHERE age = :age and email = :email and balance = :balance";
final int age = 23;
final String email = "asd@g.c";
final float balance = 12.1f;
final String convertedAge = SimpleDBAttributeConverter.encode(age);
final String convertedBalance = SimpleDBAttributeConverter.encode(balance);
String expectedQuery = "select * from customer_all WHERE age = '" + convertedAge + "' and email = '" + email
+ "' and balance = '" + convertedBalance + "'";
final Parameters parameters = getMockParameters(new String[]{":age", ":email", ":balance"}, new Class[]{int.class, String.class, float.class});
String resultedQuery = QueryUtils.buildQuery(bind_query, parameters, age, email,
balance);
assertThat(resultedQuery, is(expectedQuery));
}
@Test
public void buildQueryConditionsWithParameters_should_construct_correct_query_for_Date_parameter() {
final String bindQueryWithDate = "select * from customer_all WHERE date = :date";
final Date date = new Date();
final String convertedDate = SimpleDBAttributeConverter.encode(date);
String expectedQuery = "select * from customer_all WHERE date = '" + convertedDate + "'";
final Parameters parameters = getMockParameters(new String[]{":date"}, new Class[]{String.class});
String resultedQuery = QueryUtils.buildQuery(bindQueryWithDate, parameters, date);
assertThat(resultedQuery, is(expectedQuery));
}
@Test
public void buildQueryConditionsWithParameters_should_construct_correct_query_for_primitive_array_parameter() {
final String bindQueryWithDate = "select * from customer_all WHERE byte_array = :byte_array";
final byte[] byteArray = new byte[] { 1, 2, 5 };
final String convertedByteArray = SimpleDBAttributeConverter.encode(byteArray);
String expectedQuery = "select * from customer_all WHERE byte_array = '" + convertedByteArray + "'";
final Parameters parameters = getMockParameters(new String[]{":byte_array"}, new Class[]{String.class});
String resultedQuery = QueryUtils.buildQuery(bindQueryWithDate, parameters, byteArray);
assertThat(resultedQuery, is(expectedQuery));
}
@Test(expected = MappingException.class)
public void validateBindParametersCount_should_fail_if_wrong_number_of_parameters_and_values() {
QueryUtils.validateBindParametersCount(getMockParameters(":param_1", ":param_2", ":param_3"), "value1");
}
@Test
public void validateBindParametersTypes_should_pass_for_supported_primitive_types() {
QueryUtils.validateBindParametersTypes(getMockParameters(new String[] { ":int", ":long", ":double", ":float",
":boolean", ":short", ":byte" }, new Class[] { int.class, long.class, double.class, float.class,
boolean.class, short.class, byte.class }));
}
@Test
public void validateBindParametersTypes_should_pass_for_supported_core_types() {
QueryUtils.validateBindParametersTypes(getMockParameters(new String[] { ":string", ":date", ":int", ":long",
":double", ":float", ":boolean", ":short", ":byte" }, new Class[] { String.class, Date.class,
Integer.class, Long.class, Double.class, Float.class, Boolean.class, Short.class, Byte.class }));
}
@Test
public void validateBindParametersTypes_should_pass_for_primitive_array_types() {
QueryUtils.validateBindParametersTypes(getMockParameters(new String[] { ":int", ":long", ":double", ":float",
":boolean", ":short", ":byte" }, new Class[] { int[].class, long[].class, double[].class,
float[].class, boolean[].class, short[].class, byte[].class }));
}
@Test
public void validateBindParametersTypes_should_pass_for_special_types() {
QueryUtils.validateBindParametersTypes(getMockParameters(new String[] { ":pageable", ":sort" }, new Class[] {
Pageable.class, Sort.class }));
}
@Test(expected = IllegalArgumentException.class)
public void validateBindParametersTypes_should_fail_for_unsupported_types() {
QueryUtils.validateBindParametersTypes(getMockParameters(new String[] { ":param_1" },
new Class[] { SimpleDbSampleEntity.class }));
}
@Ignore
@Test
public void buildQueryConditionsWithParameters_should_work_with_complex_parameters() {
final String expectedQuery = "select * from spring_data where name = 'spring-name' and type = 'spring-type'";
final String rawQuery = "select * from spring_data where name = ::name and type = :";
final Parameters parameters = getMockParameters(new String[]{"::name", ":"}, new Class[]{String.class, String.class});
String resultedQuery = QueryUtils.buildQuery(rawQuery, parameters, "spring-name",
"spring-type");
assertThat(resultedQuery, is(expectedQuery));
}
@Test
public void like_operators_should_be_wrapped_in_quotes() {
final String expectedQuery = "select * from spring_data where first_name like '%joe' and last_name like 'dev%' and middle_name like '%o%'";
final String rawQuery = "select * from spring_data where first_name like %:fname and last_name like :lname% and middle_name like %:mname%";
final Parameters parameters = getMockParameters(new String[]{":fname", ":lname", ":mname"}, new Class[]{String.class, String.class, String.class});
String resultedQuery = QueryUtils.buildQuery(rawQuery, parameters, "joe",
"dev", "o");
assertThat(resultedQuery, is(expectedQuery));
}
static final List<Class<?>> TYPES = Arrays.<Class<?>>asList(Pageable.class, Sort.class);
@SuppressWarnings({ "rawtypes", "unchecked" })
private Parameter getMockParameter(String placeHolder, Integer idx, Class clazz) {
Parameter mockParameter = Mockito.mock(Parameter.class);
Mockito.when(mockParameter.getPlaceholder()).thenReturn(placeHolder);
Mockito.when(mockParameter.isNamedParameter()).thenReturn(Boolean.TRUE);
Mockito.when(mockParameter.getIndex()).thenReturn(idx);
Mockito.when(mockParameter.getType()).thenReturn(clazz);
Mockito.when(mockParameter.isSpecialParameter()).thenReturn(TYPES.contains(clazz));
return mockParameter;
}
private Parameters getMockParameters(String... placeHolders) {
return getMockParameters(placeHolders, new Class[placeHolders.length]);
}
@SuppressWarnings({ "rawtypes" })
private Parameters getMockParameters(String[] placeHolders, Class[] clazzes) {
Parameters mockParameters = Mockito.mock(Parameters.class);
List<Parameter> parameters = new ArrayList<Parameter>(placeHolders.length);
for(int idx = 0; idx < placeHolders.length; ++idx) {
parameters.add(getMockParameter(placeHolders[idx], idx, clazzes[idx]));
}
Mockito.when(mockParameters.iterator()).thenReturn(parameters.iterator());
Mockito.when(mockParameters.getNumberOfParameters()).thenReturn(parameters.size());
return mockParameters;
}
}