package org.molgenis.data.rest.service; import org.mockito.ArgumentCaptor; import org.molgenis.data.DataService; import org.molgenis.data.Entity; import org.molgenis.data.EntityManager; import org.molgenis.data.MolgenisDataException; import org.molgenis.data.meta.AttributeType; import org.molgenis.data.meta.model.Attribute; import org.molgenis.data.meta.model.EntityType; import org.molgenis.data.populate.IdGenerator; import org.molgenis.file.FileStore; import org.molgenis.file.model.FileMetaFactory; import org.molgenis.util.MolgenisDateFormat; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.text.ParseException; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.stream.Stream; import static com.google.common.collect.Lists.newArrayList; import static java.util.Collections.emptyList; import static java.util.stream.Collectors.toList; import static org.mockito.Mockito.*; import static org.molgenis.data.meta.AttributeType.*; import static org.testng.Assert.assertEquals; public class RestServiceTest { private RestService restService; private EntityManager entityManager; private DataService dataService; @BeforeMethod public void setUpBeforeMethod() { dataService = mock(DataService.class); IdGenerator idGenerator = mock(IdGenerator.class); FileStore fileStore = mock(FileStore.class); FileMetaFactory fileMetaFactory = mock(FileMetaFactory.class); entityManager = mock(EntityManager.class); this.restService = new RestService(dataService, idGenerator, fileStore, fileMetaFactory, entityManager); } @Test public void toEntityValue() { Attribute attr = mock(Attribute.class); when(attr.getDataType()).thenReturn(MREF); assertEquals(restService.toEntityValue(attr, null), emptyList()); } // https://github.com/molgenis/molgenis/issues/4725 @DataProvider(name = "toEntityValueMrefProvider") public static Iterator<Object[]> toEntityValueMrefProvider() { return newArrayList(new Object[] { MREF }, new Object[] { ONE_TO_MANY }).iterator(); } @Test(dataProvider = "toEntityValueMrefProvider") public void toEntityValueMrefToIntAttr(AttributeType attrType) { Entity entity0 = mock(Entity.class); Entity entity1 = mock(Entity.class); String refEntityName = "refEntity"; Attribute refIdAttr = mock(Attribute.class); when(refIdAttr.getDataType()).thenReturn(INT); EntityType refEntityType = mock(EntityType.class); when(refEntityType.getName()).thenReturn(refEntityName); when(refEntityType.getIdAttribute()).thenReturn(refIdAttr); Attribute attr = mock(Attribute.class); when(attr.getDataType()).thenReturn(attrType); when(attr.getRefEntity()).thenReturn(refEntityType); when(entityManager.getReference(refEntityType, 0)).thenReturn(entity0); when(entityManager.getReference(refEntityType, 1)).thenReturn(entity1); Object entityValue = restService.toEntityValue(attr, "0,1"); // string assertEquals(entityValue, Arrays.asList(entity0, entity1)); } @Test(dataProvider = "toEntityValueMrefProvider") public void toEntityValueMrefToStringAttr(AttributeType attrType) { Entity entity0 = mock(Entity.class); Entity entity1 = mock(Entity.class); String refEntityName = "refEntity"; Attribute refIdAttr = mock(Attribute.class); when(refIdAttr.getDataType()).thenReturn(STRING); EntityType refEntityType = mock(EntityType.class); when(refEntityType.getName()).thenReturn(refEntityName); when(refEntityType.getIdAttribute()).thenReturn(refIdAttr); Attribute attr = mock(Attribute.class); when(attr.getDataType()).thenReturn(attrType); when(attr.getRefEntity()).thenReturn(refEntityType); when(entityManager.getReference(refEntityType, "0")).thenReturn(entity0); when(entityManager.getReference(refEntityType, "1")).thenReturn(entity1); Object entityValue = restService.toEntityValue(attr, "0,1"); // string assertEquals(entityValue, Arrays.asList(entity0, entity1)); } @Test public void toEntityValueXref() { Entity entity0 = mock(Entity.class); String refEntityName = "refEntity"; Attribute refIdAttr = mock(Attribute.class); when(refIdAttr.getDataType()).thenReturn(STRING); EntityType refEntityMeta = mock(EntityType.class); when(refEntityMeta.getName()).thenReturn(refEntityName); when(refEntityMeta.getIdAttribute()).thenReturn(refIdAttr); Attribute attr = mock(Attribute.class); when(attr.getDataType()).thenReturn(XREF); when(attr.getRefEntity()).thenReturn(refEntityMeta); when(entityManager.getReference(refEntityMeta, "0")).thenReturn(entity0); assertEquals(restService.toEntityValue(attr, "0"), entity0); } @Test public void toEntityDateStringValueValid() throws ParseException { Attribute dateAttr = when(mock(Attribute.class).getName()).thenReturn("dateAttr").getMock(); when(dateAttr.getDataType()).thenReturn(DATE); assertEquals(restService.toEntityValue(dateAttr, "2000-12-31"), MolgenisDateFormat.getDateFormat().parse("2000-12-31")); } @Test(expectedExceptions = MolgenisDataException.class, expectedExceptionsMessageRegExp = "Attribute \\[dateAttr\\] value \\[invalidDate\\] does not match date format \\[yyyy-MM-dd\\]") public void toEntityDateStringValueInvalid() { Attribute dateAttr = when(mock(Attribute.class).getName()).thenReturn("dateAttr").getMock(); when(dateAttr.getDataType()).thenReturn(DATE); restService.toEntityValue(dateAttr, "invalidDate"); } @Test public void updateMappedByEntitiesEntity() { String refEntityName = "refEntityName"; EntityType refEntityMeta = mock(EntityType.class); when(refEntityMeta.getName()).thenReturn(refEntityName); String mappedByAttrName = "mappedByAttr"; Attribute mappedByAttr = mock(Attribute.class); when(mappedByAttr.getName()).thenReturn(mappedByAttrName); EntityType entityMeta = mock(EntityType.class); Attribute oneToManyAttr = mock(Attribute.class); String oneToManyAttrName = "oneToManyAttr"; when(oneToManyAttr.getName()).thenReturn(oneToManyAttrName); when(oneToManyAttr.getDataType()).thenReturn(ONE_TO_MANY); when(oneToManyAttr.isMappedBy()).thenReturn(true); when(oneToManyAttr.getMappedBy()).thenReturn(mappedByAttr); when(oneToManyAttr.getRefEntity()).thenReturn(refEntityMeta); when(entityMeta.getMappedByAttributes()).thenReturn(Stream.of(oneToManyAttr)); Entity refEntity0 = mock(Entity.class); Entity refEntity1 = mock(Entity.class); Entity entity = mock(Entity.class); when(entity.getEntities(oneToManyAttrName)).thenReturn(newArrayList(refEntity0, refEntity1)); when(entity.getEntityType()).thenReturn(entityMeta); restService.updateMappedByEntities(entity); //noinspection unchecked ArgumentCaptor<Stream<Entity>> captor = ArgumentCaptor.forClass((Class) Stream.class); verify(dataService).update(eq(refEntityName), captor.capture()); List<Entity> refEntities = captor.getValue().collect(toList()); assertEquals(refEntities, newArrayList(refEntity0, refEntity1)); verify(refEntity0).set(mappedByAttrName, entity); verify(refEntity1).set(mappedByAttrName, entity); verifyNoMoreInteractions(dataService); } @Test public void updateMappedByEntitiesEntityEntity() { String refEntityName = "refEntityName"; EntityType refEntityMeta = mock(EntityType.class); when(refEntityMeta.getName()).thenReturn(refEntityName); String mappedByAttrName = "mappedByAttr"; Attribute mappedByAttr = mock(Attribute.class); when(mappedByAttr.getName()).thenReturn(mappedByAttrName); EntityType entityMeta = mock(EntityType.class); Attribute oneToManyAttr = mock(Attribute.class); String oneToManyAttrName = "oneToManyAttr"; when(oneToManyAttr.getName()).thenReturn(oneToManyAttrName); when(oneToManyAttr.getDataType()).thenReturn(ONE_TO_MANY); when(oneToManyAttr.isMappedBy()).thenReturn(true); when(oneToManyAttr.getMappedBy()).thenReturn(mappedByAttr); when(oneToManyAttr.getRefEntity()).thenReturn(refEntityMeta); when(entityMeta.getMappedByAttributes()).thenReturn(Stream.of(oneToManyAttr)); Entity refEntity0 = when(mock(Entity.class).getIdValue()).thenReturn("refEntity0").getMock(); Entity refEntity1 = when(mock(Entity.class).getIdValue()).thenReturn("refEntity1").getMock(); Entity refEntity2 = when(mock(Entity.class).getIdValue()).thenReturn("refEntity2").getMock(); Entity entity = mock(Entity.class); when(entity.getEntities(oneToManyAttrName)).thenReturn(newArrayList(refEntity0, refEntity1)); when(entity.getEntityType()).thenReturn(entityMeta); Entity existingEntity = mock(Entity.class); when(existingEntity.getEntities(oneToManyAttrName)).thenReturn(newArrayList(refEntity1, refEntity2)); when(existingEntity.getEntityType()).thenReturn(entityMeta); restService.updateMappedByEntities(entity, existingEntity); //noinspection unchecked ArgumentCaptor<Stream<Entity>> captor = ArgumentCaptor.forClass((Class) Stream.class); verify(dataService).update(eq(refEntityName), captor.capture()); List<Entity> refEntities = captor.getValue().collect(toList()); assertEquals(refEntities, newArrayList(refEntity0, refEntity2)); verify(refEntity0).set(mappedByAttrName, entity); verify(refEntity2).set(mappedByAttrName, null); verifyNoMoreInteractions(dataService); } }