/* * Copyright 2011-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.repository.core.support; import static org.assertj.core.api.Assertions.*; import java.io.Serializable; import java.lang.reflect.Method; import java.util.Collection; import org.junit.Test; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.util.ClassUtils; import com.google.common.base.Optional; /** * Unit tests for {@link DefaultRepositoryMetadata}. * * @author Oliver Gierke * @author Thomas Darimont */ public class DefaultRepositoryMetadataUnitTests { @Test(expected = IllegalArgumentException.class) public void preventsNullRepositoryInterface() { new DefaultRepositoryMetadata(null); } @Test(expected = IllegalArgumentException.class) public void rejectsNonInterface() { new DefaultRepositoryMetadata(Object.class); } @Test(expected = IllegalArgumentException.class) public void rejectsNonRepositoryInterface() { new DefaultRepositoryMetadata(Collection.class); } @Test(expected = IllegalArgumentException.class) // DATACMNS-406 public void rejectsUnparameterizedRepositoryInterface() { new DefaultRepositoryMetadata(Repository.class); } @Test public void looksUpDomainClassCorrectly() throws Exception { RepositoryMetadata metadata = new DefaultRepositoryMetadata(UserRepository.class); assertThat(metadata.getDomainType()).isEqualTo(User.class); metadata = new DefaultRepositoryMetadata(SomeDao.class); assertThat(metadata.getDomainType()).isEqualTo(User.class); } @Test public void findsDomainClassOnExtensionOfDaoInterface() throws Exception { RepositoryMetadata metadata = new DefaultRepositoryMetadata(ExtensionOfUserCustomExtendedDao.class); assertThat(metadata.getDomainType()).isEqualTo(User.class); } @Test public void detectsParameterizedEntitiesCorrectly() { RepositoryMetadata metadata = new DefaultRepositoryMetadata(GenericEntityRepository.class); assertThat(metadata.getDomainType()).isEqualTo(GenericEntity.class); } @Test public void looksUpIdClassCorrectly() throws Exception { RepositoryMetadata metadata = new DefaultRepositoryMetadata(UserRepository.class); assertThat(metadata.getIdType()).isEqualTo(Integer.class); } @Test // DATACMNS-442 public void detectsIdTypeOnIntermediateRepository() { RepositoryMetadata metadata = new DefaultRepositoryMetadata(ConcreteRepository.class); assertThat(metadata.getIdType()).isEqualTo(Long.class); } @Test // DATACMNS-483 public void discoversDomainTypeOnReturnTypeWrapper() throws Exception { RepositoryMetadata metadata = new DefaultRepositoryMetadata(OptionalRepository.class); Method method = OptionalRepository.class.getMethod("findByEmailAddress", String.class); assertThat(metadata.getReturnedDomainClass(method)).isEqualTo(User.class); } @Test // DATACMNS-483 public void discoversDomainTypeOnNestedReturnTypeWrapper() throws Exception { RepositoryMetadata metadata = new DefaultRepositoryMetadata(OptionalRepository.class); Method method = OptionalRepository.class.getMethod("findByLastname", String.class); assertThat(metadata.getReturnedDomainClass(method)).isEqualTo(User.class); } @Test // DATACMNS-501 public void discoversDomainAndIdTypeForIntermediateRepository() { RepositoryMetadata metadata = new DefaultRepositoryMetadata(IdTypeFixingRepository.class); assertThat(metadata.getDomainType()).isEqualTo(Object.class); assertThat(metadata.getIdType()).isEqualTo(Long.class); } @SuppressWarnings("unused") private class User { private String firstname; public String getAddress() { return null; } } static interface UserRepository extends CrudRepository<User, Integer> { } /** * Sample interface to serve two purposes: * <ol> * <li>Check that {@link ClassUtils#getDomainClass(Class)} skips non {@link GenericDao} interfaces</li> * <li>Check that {@link ClassUtils#getDomainClass(Class)} traverses interface hierarchy</li> * </ol> * * @author Oliver Gierke */ private interface SomeDao extends Serializable, UserRepository { Page<User> findByFirstname(Pageable pageable, String firstname); } /** * Sample interface to test recursive lookup of domain class. * * @author Oliver Gierke */ static interface ExtensionOfUserCustomExtendedDao extends UserCustomExtendedRepository { } static interface UserCustomExtendedRepository extends CrudRepository<User, Integer> { } static abstract class DummyGenericRepositorySupport<T, ID extends Serializable> implements CrudRepository<T, ID> { public java.util.Optional<T> findById(ID id) { return java.util.Optional.empty(); } } /** * Helper class to reproduce #256. * * @author Oliver Gierke */ static class GenericEntity<T> {} static interface GenericEntityRepository extends CrudRepository<GenericEntity<String>, Long> {} static interface IdTypeFixingRepository<T> extends Repository<T, Long> { } static interface ConcreteRepository extends IdTypeFixingRepository<User> { } static interface OptionalRepository extends Repository<User, Long> { Optional<User> findByEmailAddress(String emailAddress); // Contrived example but to make sure recursive wrapper resolution works Optional<Optional<User>> findByLastname(String lastname); } }