/**
* ***************************************************************************
* Copyright (c) 2010 Qcadoo Limited
* Project: Qcadoo Framework
* Version: 1.4
*
* This file is part of Qcadoo.
*
* Qcadoo is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation; either version 3 of the License,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* ***************************************************************************
*/
package com.qcadoo.model.internal;
import com.google.common.collect.Lists;
import com.qcadoo.model.api.DataDefinition;
import com.qcadoo.model.api.Entity;
import com.qcadoo.model.api.FieldDefinition;
import com.qcadoo.model.api.search.SearchRestrictions;
import com.qcadoo.model.api.types.BelongsToType;
import com.qcadoo.model.beans.sample.SampleParentDatabaseObject;
import com.qcadoo.model.beans.sample.SampleSimpleDatabaseObject;
import com.qcadoo.model.internal.api.InternalDataDefinition;
import com.qcadoo.model.internal.types.IntegerType;
import com.qcadoo.model.internal.types.StringType;
import org.junit.Test;
import org.junit.matchers.JUnitMatchers;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;
import static junit.framework.Assert.*;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.*;
import static org.springframework.util.Assert.isInstanceOf;
public class EntityServiceImplTest extends DataAccessTest {
@Test(expected = IllegalStateException.class)
public void shouldThrownAnExceptionWhileGettingNotExistingField() throws Exception {
// given
SampleSimpleDatabaseObject databaseEntity = new SampleSimpleDatabaseObject(1L);
FieldDefinition fieldDefinition = new FieldDefinitionImpl(new DataDefinitionImpl("", "", null), "unknown");
// when
entityService.getField(databaseEntity, fieldDefinition);
}
@Test
public void shouldReturnNullWhileGettingEmptyField() throws Exception {
// given
SampleSimpleDatabaseObject databaseEntity = new SampleSimpleDatabaseObject(1L);
// when
Object value = entityService.getField(databaseEntity, fieldDefinitionName);
// then
assertNull(value);
}
@Test
public void shouldReturnProperValueOfTheField() throws Exception {
// given
SampleSimpleDatabaseObject databaseEntity = new SampleSimpleDatabaseObject(1L);
databaseEntity.setName("Mr T");
// when
Object value = entityService.getField(databaseEntity, fieldDefinitionName);
// then
assertEquals("Mr T", value);
}
@Test
public void shouldReturnProperValueOfTheBelongsToField() throws Exception {
// given
SampleParentDatabaseObject parentDatabaseEntity = new SampleParentDatabaseObject(1L);
parentDatabaseEntity.setName("Mr X");
SampleSimpleDatabaseObject databaseEntity = new SampleSimpleDatabaseObject(2L);
databaseEntity.setName("Mr T");
databaseEntity.setBelongsTo(parentDatabaseEntity);
// when
Object value = entityService.getField(databaseEntity, fieldDefinitionBelongsTo);
// then
isInstanceOf(Entity.class, value);
assertEquals(Long.valueOf(1), ((Entity) value).getId());
assertEquals("Mr X", ((Entity) value).getField("name"));
}
@Test
public void shouldNotThrownAnExceptionWhileGettingFieldWithInvalidType() throws Exception {
// given
SampleSimpleDatabaseObject databaseEntity = new SampleSimpleDatabaseObject(1L);
databaseEntity.setName("Mr T");
FieldDefinition fieldDefinition = new FieldDefinitionImpl(new DataDefinitionImpl("", "", null), "name").withType(new IntegerType());
// when
entityService.getField(databaseEntity, fieldDefinition);
}
@Test
public void shouldReturnClassForGivenDataDefinition() throws Exception {
// when
Class<?> clazz = dataDefinition.getClassForEntity();
// then
assertEquals(SampleSimpleDatabaseObject.class, clazz);
}
@Test(expected = IllegalStateException.class)
public void shouldThrownAnExceptionIfClassForGivenDataDefinitionDoesNotExist() throws Exception {
// given
DataDefinitionImpl dataDefinition = new DataDefinitionImpl("", "definition", null);
dataDefinition.setFullyQualifiedClassName("java.lang.SomeUselessNotExistingClass");
// when
dataDefinition.getClassForEntity();
}
@Test
public void shouldReturnProperId() throws Exception {
// given
SampleSimpleDatabaseObject databaseEntity = new SampleSimpleDatabaseObject(13L);
// when
Long id = entityService.getId(databaseEntity);
// then
assertEquals(Long.valueOf(13), id);
}
@Test
public void shouldSetProperId() throws Exception {
// given
SampleSimpleDatabaseObject databaseEntity = new SampleSimpleDatabaseObject();
// when
entityService.setId(databaseEntity, 13L);
// then
assertEquals(Long.valueOf(13), databaseEntity.getId());
}
@Test(expected = IllegalStateException.class)
public void shouldThrownAnExceptionWhileSettingNotExistingField() throws Exception {
// given
SampleSimpleDatabaseObject databaseEntity = new SampleSimpleDatabaseObject(1L);
FieldDefinition fieldDefinition = new FieldDefinitionImpl(new DataDefinitionImpl("", "", null), "unknown").withType(new StringType());
// when
entityService.setField(databaseEntity, fieldDefinition, "XXX");
}
@Test
public void shouldSetEmptyField() throws Exception {
// given
SampleSimpleDatabaseObject databaseEntity = new SampleSimpleDatabaseObject(1L);
databaseEntity.setName("name");
// when
entityService.setField(databaseEntity, fieldDefinitionName, null);
// then
assertNull(databaseEntity.getName());
}
@Test
public void shouldSetNotEmptyField() throws Exception {
// given
SampleSimpleDatabaseObject databaseEntity = new SampleSimpleDatabaseObject(1L);
databaseEntity.setName("name");
// when
entityService.setField(databaseEntity, fieldDefinitionName, "XXX");
// then
assertEquals("XXX", databaseEntity.getName());
}
@Test
public void shouldSetBelongsToField() throws Exception {
// given
Entity parentEntity = new DefaultEntity(dataDefinition, 1L);
parentEntity.setField("name", "Mr X");
SampleParentDatabaseObject parentDatabaseEntity = new SampleParentDatabaseObject(1L);
parentDatabaseEntity.setName("Mr X");
SampleSimpleDatabaseObject databaseEntity = new SampleSimpleDatabaseObject(2L);
given(session.load(SampleParentDatabaseObject.class, 1L)).willReturn(parentDatabaseEntity);
// when
entityService.setField(databaseEntity, fieldDefinitionBelongsTo, parentEntity);
// then
assertNotNull(databaseEntity.getBelongsTo());
assertEquals(parentDatabaseEntity, databaseEntity.getBelongsTo());
}
@Test
public void shouldSetNullIfBelongsToFieldIsEmpty() throws Exception {
// given
SampleParentDatabaseObject parentDatabaseEntity = new SampleParentDatabaseObject(1L);
parentDatabaseEntity.setName("Mr X");
SampleSimpleDatabaseObject databaseEntity = new SampleSimpleDatabaseObject(2L);
databaseEntity.setBelongsTo(parentDatabaseEntity);
// when
entityService.setField(databaseEntity, fieldDefinitionBelongsTo, null);
// then
assertNull(databaseEntity.getBelongsTo());
}
@Test
public void shouldConvertDatabaseEntityIntoGenericOne() throws Exception {
// given
SampleParentDatabaseObject parentDatabaseEntity = new SampleParentDatabaseObject(1L);
parentDatabaseEntity.setName("Mr X");
SampleParentDatabaseObject lazyParentDatabaseEntity = mock(SampleParentDatabaseObject.class, RETURNS_DEEP_STUBS);
given(lazyParentDatabaseEntity.getHibernateLazyInitializer().getIdentifier()).willReturn(77L);
SampleSimpleDatabaseObject databaseEntity = new SampleSimpleDatabaseObject(2L);
databaseEntity.setAge(12);
databaseEntity.setName("Mr T");
databaseEntity.setBelongsTo(parentDatabaseEntity);
databaseEntity.setLazyBelongsTo(lazyParentDatabaseEntity);
// when
Entity genericEntity = entityService.convertToGenericEntity(dataDefinition, databaseEntity);
// then
assertNotNull(genericEntity);
assertEquals(Long.valueOf(2), genericEntity.getId());
assertEquals(12, genericEntity.getField("age"));
assertEquals("Mr T", genericEntity.getField("name"));
isInstanceOf(DefaultEntity.class, genericEntity.getField("belongsTo"));
assertEquals("Mr X", ((Entity) genericEntity.getField("belongsTo")).getField("name"));
isInstanceOf(ProxyEntity.class, genericEntity.getField("lazyBelongsTo"));
assertEquals(Long.valueOf(77), ((Entity) genericEntity.getField("lazyBelongsTo")).getId());
}
@Test
public void shouldConvertDatabaseEntityIntoGenericOneWithHasMany() throws Exception {
// given
SampleParentDatabaseObject parentDatabaseEntity = new SampleParentDatabaseObject(1L);
parentDatabaseEntity.setName("Mr X");
// when
Entity genericEntity = entityService.convertToGenericEntity(parentDataDefinition, parentDatabaseEntity);
// then
assertNotNull(genericEntity);
assertEquals(Long.valueOf(1), genericEntity.getId());
List<Entity> hasManyField = genericEntity.getHasManyField("entities");
Field field = ReflectionUtils.findField(EntityListImpl.class, "entities");
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field, hasManyField, Collections.emptyList());
assertThat(hasManyField, instanceOf(EntityListImpl.class));
assertEquals(dataDefinition, ReflectionTestUtils.getField(hasManyField, "dataDefinition"));
assertEquals(Long.valueOf(1), ReflectionTestUtils.getField(hasManyField, "parentId"));
assertEquals(fieldDefinitionBelongsTo, ReflectionTestUtils.getField(hasManyField, "joinFieldDefinition"));
}
@Test
public void shouldConvertGenericEntityIntoDatabaseOne() throws Exception {
// given
Entity genericEntity = new DefaultEntity(dataDefinition, 2L);
genericEntity.setField("name", "Mr T");
genericEntity.setField("age", 12);
genericEntity.setField("belongsTo", 1L);
SampleParentDatabaseObject parentDatabaseEntity = new SampleParentDatabaseObject(1L);
parentDatabaseEntity.setName("Mr X");
given(session.get(SampleParentDatabaseObject.class, 1L)).willReturn(parentDatabaseEntity);
given(session.load(SampleParentDatabaseObject.class, 1L)).willReturn(parentDatabaseEntity);
validationService.validateGenericEntity(dataDefinition, genericEntity, null);
// when
Object databaseEntity = entityService.convertToDatabaseEntity(dataDefinition, genericEntity, null);
// then
assertNotNull(databaseEntity);
isInstanceOf(SampleSimpleDatabaseObject.class, databaseEntity);
assertEquals(Long.valueOf(2), ((SampleSimpleDatabaseObject) databaseEntity).getId());
assertEquals(Integer.valueOf(12), ((SampleSimpleDatabaseObject) databaseEntity).getAge());
assertEquals("Mr T", ((SampleSimpleDatabaseObject) databaseEntity).getName());
assertNotNull(((SampleSimpleDatabaseObject) databaseEntity).getBelongsTo());
assertEquals("Mr X", ((SampleSimpleDatabaseObject) databaseEntity).getBelongsTo().getName());
}
@Test
public void shouldConvertGenericEntityIntoDatabaseOneUsingExistingEntity() throws Exception {
// given
Entity genericEntity = new DefaultEntity(dataDefinition, 2L);
genericEntity.setField("name", "Mr T");
genericEntity.setField("age", 12);
genericEntity.setField("belongsTo", 1L);
SampleSimpleDatabaseObject existingDatabaseEntity = new SampleSimpleDatabaseObject(11L);
SampleParentDatabaseObject parentDatabaseEntity = new SampleParentDatabaseObject(1L);
parentDatabaseEntity.setName("Mr X");
given(session.get(SampleParentDatabaseObject.class, 1L)).willReturn(parentDatabaseEntity);
given(session.load(SampleParentDatabaseObject.class, 1L)).willReturn(parentDatabaseEntity);
validationService.validateGenericEntity(dataDefinition, genericEntity, new DefaultEntity(dataDefinition, 2L));
// when
Object databaseEntity = entityService.convertToDatabaseEntity(dataDefinition, genericEntity, existingDatabaseEntity);
// then
assertNotNull(databaseEntity);
isInstanceOf(SampleSimpleDatabaseObject.class, databaseEntity);
assertEquals(Long.valueOf(11), ((SampleSimpleDatabaseObject) databaseEntity).getId());
assertEquals(Integer.valueOf(12), ((SampleSimpleDatabaseObject) databaseEntity).getAge());
assertEquals("Mr T", ((SampleSimpleDatabaseObject) databaseEntity).getName());
assertNotNull(((SampleSimpleDatabaseObject) databaseEntity).getBelongsTo());
assertEquals("Mr X", ((SampleSimpleDatabaseObject) databaseEntity).getBelongsTo().getName());
}
@Test
public void shouldLazyLoadEntityUsingProxy() throws Exception {
// given
DataDefinition dataDefinition = mock(DataDefinition.class);
DefaultEntity entity = new DefaultEntity(dataDefinition, 5L);
entity.setField("test", "testValue");
given(dataDefinition.get(5L)).willReturn(entity);
ProxyEntity proxyEntity = new ProxyEntity(dataDefinition, 5L);
// when
String value = (String) proxyEntity.getField("test");
// then
assertEquals("testValue", value);
}
@Test
public void shouldLazyLoadEntitiesUsingProxy() throws Exception {
// given
InternalDataDefinition dataDefinition = mock(InternalDataDefinition.class, RETURNS_DEEP_STUBS);
FieldDefinition fieldDefinition = mock(FieldDefinition.class);
BelongsToType fieldType = mock(BelongsToType.class);
Entity entity1 = new DefaultEntity(dataDefinition, 1L);
Entity entity2 = new DefaultEntity(dataDefinition, 2L);
given(fieldDefinition.getName()).willReturn("joinField");
given(fieldDefinition.getType()).willReturn(fieldType);
given(fieldType.getDataDefinition()).willReturn(dataDefinition);
given(dataDefinition.isEnabled()).willReturn(true);
given(dataDefinition.getField("joinField")).willReturn(fieldDefinition);
given(
dataDefinition.find().createAlias(fieldDefinition.getName(), fieldDefinition.getName())
.add(SearchRestrictions.eq(fieldDefinition.getName() + ".id", 5L)).list().getEntities()).willReturn(
Lists.newArrayList(entity1, entity2));
List<Entity> entityList = new EntityListImpl(dataDefinition, "joinField", 5L);
// then
assertNotNull(entityList);
assertEquals(2, entityList.size());
assertThat(entityList, JUnitMatchers.hasItems(entity1, entity2));
}
@Test
public void shouldReturnProxyIdWithoutHittingDatabase() throws Exception {
// given
DataDefinition dataDefinition = mock(DataDefinition.class);
ProxyEntity proxyEntity = new ProxyEntity(dataDefinition, 5L);
// when
Long id = proxyEntity.getId();
// then
assertEquals(Long.valueOf(5), id);
verify(dataDefinition, never()).get(anyLong());
}
}