/* * 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.mongodb.core.convert; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; import org.bson.Document; import org.junit.Before; import org.junit.Test; import org.springframework.data.convert.ConfigurableTypeInformationMapper; import org.springframework.data.convert.SimpleTypeInformationMapper; import org.springframework.data.mongodb.core.DocumentTestUtils; import org.springframework.data.util.TypeInformation; /** * Unit tests for {@link DefaultMongoTypeMapper}. * * @author Oliver Gierke */ public class DefaultMongoTypeMapperUnitTests { ConfigurableTypeInformationMapper configurableTypeInformationMapper; SimpleTypeInformationMapper simpleTypeInformationMapper; DefaultMongoTypeMapper typeMapper; @Before public void setUp() { configurableTypeInformationMapper = new ConfigurableTypeInformationMapper( Collections.singletonMap(String.class, "1")); simpleTypeInformationMapper = new SimpleTypeInformationMapper(); typeMapper = new DefaultMongoTypeMapper(); } @Test public void defaultInstanceWritesClasses() { writesTypeToField(new Document(), String.class, String.class.getName()); } @Test public void defaultInstanceReadsClasses() { Document document = new Document(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, String.class.getName()); readsTypeFromField(document, String.class); } @Test public void writesMapKeyForType() { typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList(configurableTypeInformationMapper)); writesTypeToField(new Document(), String.class, "1"); writesTypeToField(new Document(), Object.class, null); } @Test public void writesClassNamesForUnmappedValuesIfConfigured() { typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList(configurableTypeInformationMapper, simpleTypeInformationMapper)); writesTypeToField(new Document(), String.class, "1"); writesTypeToField(new Document(), Object.class, Object.class.getName()); } @Test public void readsTypeForMapKey() { typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList(configurableTypeInformationMapper)); readsTypeFromField(new Document(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, "1"), String.class); readsTypeFromField(new Document(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, "unmapped"), null); } @Test public void readsTypeLoadingClassesForUnmappedTypesIfConfigured() { typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList(configurableTypeInformationMapper, simpleTypeInformationMapper)); readsTypeFromField(new Document(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, "1"), String.class); readsTypeFromField(new Document(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Object.class.getName()), Object.class); } @Test // DATAMONGO-709 public void writesTypeRestrictionsCorrectly() { Document result = new Document(); typeMapper = new DefaultMongoTypeMapper(); typeMapper.writeTypeRestrictions(result, Collections.<Class<?>> singleton(String.class)); Document typeInfo = DocumentTestUtils.getAsDocument(result, DefaultMongoTypeMapper.DEFAULT_TYPE_KEY); List<Object> aliases = DocumentTestUtils.getAsDBList(typeInfo, "$in"); assertThat(aliases, hasSize(1)); assertThat(aliases.get(0), is((Object) String.class.getName())); } @Test public void addsFullyQualifiedClassNameUnderDefaultKeyByDefault() { writesTypeToField(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, new Document(), String.class); } @Test public void writesTypeToCustomFieldIfConfigured() { typeMapper = new DefaultMongoTypeMapper("_custom"); writesTypeToField("_custom", new Document(), String.class); } @Test public void doesNotWriteTypeInformationInCaseKeyIsSetToNull() { typeMapper = new DefaultMongoTypeMapper(null); writesTypeToField(null, new Document(), String.class); } @Test public void readsTypeFromDefaultKeyByDefault() { readsTypeFromField(new Document(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, String.class.getName()), String.class); } @Test public void readsTypeFromCustomFieldConfigured() { typeMapper = new DefaultMongoTypeMapper("_custom"); readsTypeFromField(new Document("_custom", String.class.getName()), String.class); } @Test public void returnsListForBasicDBLists() { readsTypeFromField(new Document(), null); } @Test public void returnsNullIfNoTypeInfoInDocument() { readsTypeFromField(new Document(), null); readsTypeFromField(new Document(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, ""), null); } @Test public void returnsNullIfClassCannotBeLoaded() { readsTypeFromField(new Document(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, "fooBar"), null); } @Test public void returnsNullIfTypeKeySetToNull() { typeMapper = new DefaultMongoTypeMapper(null); readsTypeFromField(new Document(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, String.class), null); } @Test public void returnsCorrectTypeKey() { assertThat(typeMapper.isTypeKey(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY), is(true)); typeMapper = new DefaultMongoTypeMapper("_custom"); assertThat(typeMapper.isTypeKey("_custom"), is(true)); assertThat(typeMapper.isTypeKey(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY), is(false)); typeMapper = new DefaultMongoTypeMapper(null); assertThat(typeMapper.isTypeKey("_custom"), is(false)); assertThat(typeMapper.isTypeKey(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY), is(false)); } private void readsTypeFromField(Document document, Class<?> type) { Optional<TypeInformation<?>> typeInfo = typeMapper.readType(document); if (type != null) { assertThat(typeInfo, is(notNullValue())); assertThat(typeInfo.get().getType(), is(typeCompatibleWith(type))); } else { assertThat(typeInfo, is(Optional.empty())); } } private void writesTypeToField(String field, Document document, Class<?> type) { typeMapper.writeType(type, document); if (field == null) { assertThat(document.keySet().isEmpty(), is(true)); } else { assertThat(document.containsKey(field), is(true)); assertThat(document.get(field), is((Object) type.getName())); } } private void writesTypeToField(Document document, Class<?> type, Object value) { typeMapper.writeType(type, document); if (value == null) { assertThat(document.keySet().isEmpty(), is(true)); } else { assertThat(document.containsKey(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY), is(true)); assertThat(document.get(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY), is(value)); } } }