/* * Copyright 2015-2017 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 * * http://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.querydsl.binding; import static org.assertj.core.api.Assertions.*; import static org.springframework.test.util.ReflectionTestUtils.*; import java.text.ParseException; import java.util.List; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.junit.Before; import org.junit.Test; import org.springframework.data.querydsl.QSpecialUser; import org.springframework.data.querydsl.QUser; import org.springframework.data.querydsl.QUserWrapper; import org.springframework.data.querydsl.SimpleEntityPathResolver; import org.springframework.data.querydsl.User; import org.springframework.data.querydsl.Users; import org.springframework.data.util.ClassTypeInformation; import org.springframework.format.support.DefaultFormattingConversionService; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import com.querydsl.collections.CollQueryFactory; import com.querydsl.core.types.Constant; import com.querydsl.core.types.Predicate; /** * Unit tests for {@link QuerydslPredicateBuilder}. * * @author Christoph Strobl * @author Oliver Gierke */ public class QuerydslPredicateBuilderUnitTests { static final ClassTypeInformation<User> USER_TYPE = ClassTypeInformation.from(User.class); static final QuerydslBindings DEFAULT_BINDINGS = new QuerydslBindings(); QuerydslPredicateBuilder builder; MultiValueMap<String, String> values; @Before public void setUp() { this.builder = new QuerydslPredicateBuilder(new DefaultFormattingConversionService(), SimpleEntityPathResolver.INSTANCE); this.values = new LinkedMultiValueMap<>(); } @Test(expected = IllegalArgumentException.class) // DATACMNS-669 public void rejectsNullConversionService() { new QuerydslPredicateBuilder(null, SimpleEntityPathResolver.INSTANCE); } @Test(expected = IllegalArgumentException.class) // DATACMNS-669 public void getPredicateShouldThrowErrorWhenBindingContextIsNull() { builder.getPredicate(null, values, null); } @Test // DATACMNS-669 public void getPredicateShouldReturnEmptyPredicateWhenPropertiesAreEmpty() { assertThat(builder.getPredicate(ClassTypeInformation.OBJECT, values, DEFAULT_BINDINGS)).isNull(); } @Test // DATACMNS-669 public void resolveArgumentShouldCreateSingleStringParameterPredicateCorrectly() throws Exception { values.add("firstname", "Oliver"); Predicate predicate = builder.getPredicate(USER_TYPE, values, DEFAULT_BINDINGS); assertThat(predicate).isEqualTo((Predicate) QUser.user.firstname.eq("Oliver")); List<User> result = CollQueryFactory.from(QUser.user, Users.USERS).where(predicate).fetchResults().getResults(); assertThat(result).containsExactly(Users.OLIVER); } @Test // DATACMNS-669 public void resolveArgumentShouldCreateNestedStringParameterPredicateCorrectly() throws Exception { values.add("address.city", "Linz"); Predicate predicate = builder.getPredicate(USER_TYPE, values, DEFAULT_BINDINGS); assertThat(predicate).isEqualTo(QUser.user.address.city.eq("Linz")); List<User> result = CollQueryFactory.from(QUser.user, Users.USERS).where(predicate).fetchResults().getResults(); assertThat(result).containsExactly(Users.CHRISTOPH); } @Test // DATACMNS-669 public void ignoresNonDomainTypeProperties() { values.add("firstname", "rand"); values.add("lastname".toUpperCase(), "al'thor"); Predicate predicate = builder.getPredicate(USER_TYPE, values, DEFAULT_BINDINGS); assertThat(predicate).isEqualTo(QUser.user.firstname.eq("rand")); } @Test // DATACMNS-669 public void forwardsNullForEmptyParameterToSingleValueBinder() { values.add("lastname", null); QuerydslBindings bindings = new QuerydslBindings(); bindings.bind(QUser.user.lastname).firstOptional((path, value) -> value.map(path::contains)); builder.getPredicate(USER_TYPE, values, bindings); } @Test // DATACMNS-734 @SuppressWarnings("unchecked") public void resolvesCommaSeparatedArgumentToArrayCorrectly() { values.add("address.lonLat", "40.740337,-73.995146"); Predicate predicate = builder.getPredicate(USER_TYPE, values, DEFAULT_BINDINGS); Constant<Object> constant = (Constant<Object>) ((List<?>) getField(getField(predicate, "mixin"), "args")).get(1); assertThat(constant.getConstant()).isEqualTo(new Double[] { 40.740337D, -73.995146D }); } @Test // DATACMNS-734 @SuppressWarnings("unchecked") public void leavesCommaSeparatedArgumentUntouchedWhenTargetIsNotAnArray() { values.add("address.city", "rivers,two"); Predicate predicate = builder.getPredicate(USER_TYPE, values, DEFAULT_BINDINGS); Constant<Object> constant = (Constant<Object>) ((List<?>) getField(getField(predicate, "mixin"), "args")).get(1); assertThat(constant.getConstant()).isEqualTo("rivers,two"); } @Test // DATACMNS-734 public void bindsDateCorrectly() throws ParseException { DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd"); String date = format.print(new DateTime()); values.add("dateOfBirth", format.print(new DateTime())); Predicate predicate = builder.getPredicate(USER_TYPE, values, DEFAULT_BINDINGS); assertThat(predicate).isEqualTo(QUser.user.dateOfBirth.eq(format.parseDateTime(date).toDate())); } @Test // DATACMNS-883 public void automaticallyInsertsAnyStepInCollectionReference() { values.add("addresses.street", "VALUE"); Predicate predicate = builder.getPredicate(USER_TYPE, values, DEFAULT_BINDINGS); assertThat(predicate).isEqualTo(QUser.user.addresses.any().street.eq("VALUE")); } @Test // DATACMNS-941 public void buildsPredicateForBindingUsingDowncast() { values.add("specialProperty", "VALUE"); QuerydslBindings bindings = new QuerydslBindings(); bindings.bind(QUser.user.as(QSpecialUser.class).specialProperty)// .first(QuerydslBindingsUnitTests.ContainsBinding.INSTANCE); assertThat(builder.getPredicate(USER_TYPE, values, bindings))// .isEqualTo(QUser.user.as(QSpecialUser.class).specialProperty.contains("VALUE")); } @Test // DATACMNS-941 public void buildsPredicateForBindingUsingNestedDowncast() { values.add("user.specialProperty", "VALUE"); QUserWrapper $ = QUserWrapper.userWrapper; QuerydslBindings bindings = new QuerydslBindings(); bindings.bind($.user.as(QSpecialUser.class).specialProperty)// .first(QuerydslBindingsUnitTests.ContainsBinding.INSTANCE); assertThat(builder.getPredicate(USER_TYPE, values, bindings))// .isEqualTo($.user.as(QSpecialUser.class).specialProperty.contains("VALUE")); } }