/* * Copyright 2011-2017 by the original author(s). * * 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.mongodb.core.mapping; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.context.ApplicationContext; import org.springframework.core.annotation.AliasFor; import org.springframework.data.mapping.model.MappingException; import org.springframework.data.util.ClassTypeInformation; /** * Unit tests for {@link BasicMongoPersistentEntity}. * * @author Oliver Gierke * @author Christoph Strobl */ @RunWith(MockitoJUnitRunner.class) public class BasicMongoPersistentEntityUnitTests { @Mock ApplicationContext context; @Mock MongoPersistentProperty propertyMock; @Test public void subclassInheritsAtDocumentAnnotation() { BasicMongoPersistentEntity<Person> entity = new BasicMongoPersistentEntity<Person>( ClassTypeInformation.from(Person.class)); assertThat(entity.getCollection(), is("contacts")); } @Test public void evaluatesSpELExpression() { MongoPersistentEntity<Company> entity = new BasicMongoPersistentEntity<Company>( ClassTypeInformation.from(Company.class)); assertThat(entity.getCollection(), is("35")); } @Test // DATAMONGO-65, DATAMONGO-1108 public void collectionAllowsReferencingSpringBean() { CollectionProvider provider = new CollectionProvider(); provider.collectionName = "reference"; when(context.getBean("myBean")).thenReturn(provider); when(context.containsBean("myBean")).thenReturn(true); BasicMongoPersistentEntity<DynamicallyMapped> entity = new BasicMongoPersistentEntity<DynamicallyMapped>( ClassTypeInformation.from(DynamicallyMapped.class)); entity.setApplicationContext(context); assertThat(entity.getCollection(), is("reference")); provider.collectionName = "otherReference"; assertThat(entity.getCollection(), is("otherReference")); } @Test // DATAMONGO-937 public void shouldDetectLanguageCorrectly() { BasicMongoPersistentEntity<DocumentWithLanguage> entity = new BasicMongoPersistentEntity<DocumentWithLanguage>( ClassTypeInformation.from(DocumentWithLanguage.class)); assertThat(entity.getLanguage(), is("spanish")); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test(expected = MappingException.class) // DATAMONGO-1053 public void verifyShouldThrowExceptionForInvalidTypeOfExplicitLanguageProperty() { BasicMongoPersistentEntity<AnyDocument> entity = new BasicMongoPersistentEntity<AnyDocument>( ClassTypeInformation.from(AnyDocument.class)); when(propertyMock.isExplicitLanguageProperty()).thenReturn(true); when(propertyMock.getActualType()).thenReturn((Class) Number.class); entity.addPersistentProperty(propertyMock); entity.verify(); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test // DATAMONGO-1053 public void verifyShouldPassForStringAsExplicitLanguageProperty() { BasicMongoPersistentEntity<AnyDocument> entity = new BasicMongoPersistentEntity<AnyDocument>( ClassTypeInformation.from(AnyDocument.class)); when(propertyMock.isExplicitLanguageProperty()).thenReturn(true); when(propertyMock.getActualType()).thenReturn((Class) String.class); entity.addPersistentProperty(propertyMock); entity.verify(); verify(propertyMock, times(1)).isExplicitLanguageProperty(); verify(propertyMock, times(1)).getActualType(); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test // DATAMONGO-1053 public void verifyShouldIgnoreNonExplicitLanguageProperty() { BasicMongoPersistentEntity<AnyDocument> entity = new BasicMongoPersistentEntity<AnyDocument>( ClassTypeInformation.from(AnyDocument.class)); when(propertyMock.isExplicitLanguageProperty()).thenReturn(false); entity.addPersistentProperty(propertyMock); entity.verify(); verify(propertyMock, times(1)).isExplicitLanguageProperty(); verify(propertyMock, never()).getActualType(); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test(expected = MappingException.class) // DATAMONGO-1157 public void verifyShouldThrowErrorForLazyDBRefOnFinalClass() { BasicMongoPersistentEntity<AnyDocument> entity = new BasicMongoPersistentEntity<AnyDocument>( ClassTypeInformation.from(AnyDocument.class)); org.springframework.data.mongodb.core.mapping.DBRef dbRefMock = mock( org.springframework.data.mongodb.core.mapping.DBRef.class); when(propertyMock.isDbReference()).thenReturn(true); when(propertyMock.getDBRef()).thenReturn(dbRefMock); when(dbRefMock.lazy()).thenReturn(true); when(propertyMock.getActualType()).thenReturn((Class) Class.class); entity.addPersistentProperty(propertyMock); entity.verify(); } @Test(expected = MappingException.class) // DATAMONGO-1157 public void verifyShouldThrowErrorForLazyDBRefArray() { BasicMongoPersistentEntity<AnyDocument> entity = new BasicMongoPersistentEntity<AnyDocument>( ClassTypeInformation.from(AnyDocument.class)); org.springframework.data.mongodb.core.mapping.DBRef dbRefMock = mock( org.springframework.data.mongodb.core.mapping.DBRef.class); when(propertyMock.isDbReference()).thenReturn(true); when(propertyMock.getDBRef()).thenReturn(dbRefMock); when(dbRefMock.lazy()).thenReturn(true); when(propertyMock.isArray()).thenReturn(true); entity.addPersistentProperty(propertyMock); entity.verify(); } @Test // DATAMONGO-1157 @SuppressWarnings({ "unchecked", "rawtypes" }) public void verifyShouldPassForLazyDBRefOnNonArrayNonFinalClass() { BasicMongoPersistentEntity<AnyDocument> entity = new BasicMongoPersistentEntity<AnyDocument>( ClassTypeInformation.from(AnyDocument.class)); org.springframework.data.mongodb.core.mapping.DBRef dbRefMock = mock( org.springframework.data.mongodb.core.mapping.DBRef.class); when(propertyMock.isDbReference()).thenReturn(true); when(propertyMock.getDBRef()).thenReturn(dbRefMock); when(dbRefMock.lazy()).thenReturn(true); when(propertyMock.getActualType()).thenReturn((Class) Object.class); entity.addPersistentProperty(propertyMock); entity.verify(); verify(propertyMock, times(1)).isDbReference(); } @Test // DATAMONGO-1157 @SuppressWarnings({ "unchecked", "rawtypes" }) public void verifyShouldPassForNonLazyDBRefOnFinalClass() { BasicMongoPersistentEntity<AnyDocument> entity = new BasicMongoPersistentEntity<AnyDocument>( ClassTypeInformation.from(AnyDocument.class)); org.springframework.data.mongodb.core.mapping.DBRef dbRefMock = mock( org.springframework.data.mongodb.core.mapping.DBRef.class); when(propertyMock.isDbReference()).thenReturn(true); when(propertyMock.getDBRef()).thenReturn(dbRefMock); when(dbRefMock.lazy()).thenReturn(false); entity.addPersistentProperty(propertyMock); entity.verify(); verify(dbRefMock, times(1)).lazy(); } @Test // DATAMONGO-1291 public void metaInformationShouldBeReadCorrectlyFromInheritedDocumentAnnotation() { BasicMongoPersistentEntity<DocumentWithCustomAnnotation> entity = new BasicMongoPersistentEntity<DocumentWithCustomAnnotation>( ClassTypeInformation.from(DocumentWithCustomAnnotation.class)); assertThat(entity.getCollection(), is("collection-1")); } @Test // DATAMONGO-1373 public void metaInformationShouldBeReadCorrectlyFromComposedDocumentAnnotation() { BasicMongoPersistentEntity<DocumentWithComposedAnnotation> entity = new BasicMongoPersistentEntity<DocumentWithComposedAnnotation>( ClassTypeInformation.from(DocumentWithComposedAnnotation.class)); assertThat(entity.getCollection(), is("custom-collection")); } @Document(collection = "contacts") class Contact {} class Person extends Contact {} @Document(collection = "#{35}") class Company {} @Document(collection = "#{myBean.collectionName}") class DynamicallyMapped {} class CollectionProvider { String collectionName; public String getCollectionName() { return collectionName; } } @Document(language = "spanish") static class DocumentWithLanguage {} static class AnyDocument {} @CustomDocumentAnnotation static class DocumentWithCustomAnnotation {} @ComposedDocumentAnnotation static class DocumentWithComposedAnnotation {} @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE }) @Document(collection = "collection-1") static @interface CustomDocumentAnnotation { } @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE }) @Document static @interface ComposedDocumentAnnotation { @AliasFor(annotation = Document.class, attribute = "collection") String name() default "custom-collection"; } }