package org.molgenis.data.vcf.importer; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.mockito.*; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.molgenis.data.*; import org.molgenis.data.importer.EntitiesValidationReport; import org.molgenis.data.importer.EntityImportReport; import org.molgenis.data.meta.MetaDataService; import org.molgenis.data.meta.model.Attribute; import org.molgenis.data.meta.model.EntityType; import org.molgenis.data.support.AbstractRepository; import org.molgenis.data.vcf.model.VcfAttributes; import org.molgenis.security.permission.PermissionSystemService; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.io.File; import java.util.*; import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.Stream; import static java.util.Collections.*; import static org.mockito.Matchers.any; import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.*; import static org.molgenis.data.meta.AttributeType.MREF; import static org.testng.Assert.*; public class VcfImporterServiceTest { private VcfImporterService vcfImporterService; @Mock private DataService dataService; @Mock private PermissionSystemService permissionSystemService; @Mock private MetaDataService metaDataService; @Mock private SecurityContext securityContext; @Mock private RepositoryCollection repositoryCollection; @Captor private ArgumentCaptor<Consumer<List<Entity>>> consumerArgumentCaptor; @BeforeMethod public void setUpBeforeMethod() { MockitoAnnotations.initMocks(this); vcfImporterService = new VcfImporterService(dataService, permissionSystemService, metaDataService); when(dataService.getMeta()).thenReturn(metaDataService); SecurityContextHolder.setContext(securityContext); when(metaDataService.getDefaultBackend()).thenReturn(repositoryCollection); when(repositoryCollection.getName()).thenReturn("default"); } @SuppressWarnings("unchecked") @Test public void doImportVcfWithoutSamples() { // Test with multiple input repositories not possible due to // https://github.com/molgenis/molgenis/issues/4544 String entityName0 = "entity0"; List<String> entityNames = Arrays.asList(entityName0); EntityType entityType0 = mock(EntityType.class); when(entityType0.getName()).thenReturn(entityName0); when(entityType0.getSimpleName()).thenReturn(entityName0); when(entityType0.getOwnAttributes()).thenReturn(emptyList()); when(entityType0.getOwnLookupAttributes()).thenReturn(emptyList()); Entity entity0 = mock(Entity.class); Entity entity1 = mock(Entity.class); List<Entity> entities = Arrays.asList(entity0, entity1); Repository<Entity> repo0 = Mockito.spy(new AbstractRepository() { @Override public Set<RepositoryCapability> getCapabilities() { return null; } public EntityType getEntityType() { return entityType0; } @Override public Iterator<Entity> iterator() { return entities.iterator(); } @Override public Spliterator<Entity> spliterator() { return entities.spliterator(); } @Override public String getName() { return entityName0; } @Override public void forEachBatched(Consumer<List<Entity>> consumer, int batchSize) { this.forEachBatched(null, consumer, batchSize); } }); when(dataService.hasRepository(entityName0)).thenReturn(false); Repository<Entity> outRepo0 = mock(Repository.class); when(metaDataService.createRepository(argThat(eqName(entityType0)))).thenReturn(outRepo0); when(outRepo0.add(any(Stream.class))).thenAnswer(new Answer<Integer>() { @Override public Integer answer(InvocationOnMock invocation) throws Throwable { Stream<Entity> entities = (Stream<Entity>) invocation.getArguments()[0]; List<Entity> entityList = entities.collect(Collectors.toList()); return entityList.size(); } }); RepositoryCollection source = mock(RepositoryCollection.class); when(source.getEntityNames()).thenReturn(entityNames); when(source.getRepository(entityName0)).thenReturn(repo0); String defaultPackage = "package"; EntityImportReport entityImportReport = vcfImporterService.doImport(source, DatabaseAction.ADD, defaultPackage); EntityImportReport expectedEntityImportReport = new EntityImportReport(); expectedEntityImportReport.addEntityCount(entityName0, entities.size()); expectedEntityImportReport.addNewEntity(entityName0); assertEquals(entityImportReport, expectedEntityImportReport); verify(metaDataService, times(1)).createRepository(argThat(eqName(entityType0))); verify(permissionSystemService, times(1)) .giveUserEntityPermissions(securityContext, singletonList(entityName0)); } @SuppressWarnings("unchecked") @Test public void doImportVcfWithSamples() { // Test with multiple input repositories not possible due to // https://github.com/molgenis/molgenis/issues/4544 String entityName0 = "entity0"; List<String> entityNames = Arrays.asList(entityName0); String sampleEntityName0 = "entity0sample"; EntityType sampleEntityType0 = mock(EntityType.class); when(sampleEntityType0.getName()).thenReturn(sampleEntityName0); when(sampleEntityType0.getSimpleName()).thenReturn(sampleEntityName0); when(sampleEntityType0.getOwnAttributes()).thenReturn(emptyList()); when(sampleEntityType0.getOwnLookupAttributes()).thenReturn(emptyList()); Repository<Entity> outSampleRepo0 = mock(Repository.class); when(outSampleRepo0.getName()).thenReturn(sampleEntityName0); when(metaDataService.createRepository(argThat(eqName(sampleEntityType0)))).thenReturn(outSampleRepo0); Attribute sampleAttr = mock(Attribute.class); when(sampleAttr.getName()).thenReturn(VcfAttributes.SAMPLES); when(sampleAttr.getRefEntity()).thenReturn(sampleEntityType0); when(sampleAttr.getDataType()).thenReturn(MREF); EntityType entityType0 = mock(EntityType.class); when(entityType0.getName()).thenReturn(entityName0); when(entityType0.getSimpleName()).thenReturn(entityName0); when(entityType0.getAttribute(VcfAttributes.SAMPLES)).thenReturn(sampleAttr); when(entityType0.getOwnAttributes()).thenReturn(singletonList(sampleAttr)); when(entityType0.getOwnLookupAttributes()).thenReturn(emptyList()); Entity entity0Sample0 = mock(Entity.class); Entity entity0Sample1 = mock(Entity.class); Entity entity1Sample0 = mock(Entity.class); Entity entity1Sample1 = mock(Entity.class); Entity entity0 = mock(Entity.class); when(entity0.getEntities(VcfAttributes.SAMPLES)).thenReturn(Arrays.asList(entity0Sample0, entity0Sample1)); Entity entity1 = mock(Entity.class); when(entity1.getEntities(VcfAttributes.SAMPLES)).thenReturn(Arrays.asList(entity1Sample0, entity1Sample1)); List<Entity> entities = Arrays.asList(entity0, entity1); Repository<Entity> repo0 = Mockito.spy(new AbstractRepository() { @Override public Set<RepositoryCapability> getCapabilities() { return null; } public EntityType getEntityType() { return entityType0; } @Override public Iterator<Entity> iterator() { return entities.iterator(); } @Override public Spliterator<Entity> spliterator() { return entities.spliterator(); } @Override public String getName() { return entityName0; } @Override public void forEachBatched(Consumer<List<Entity>> consumer, int batchSize) { this.forEachBatched(null, consumer, batchSize); } }); when(dataService.hasRepository(entityName0)).thenReturn(false); Repository<Entity> outRepo0 = mock(Repository.class); when(metaDataService.createRepository(argThat(eqName(entityType0)))).thenReturn(outRepo0); when(outRepo0.add(any(Stream.class))).thenAnswer(new Answer<Integer>() { @Override public Integer answer(InvocationOnMock invocation) throws Throwable { Stream<Entity> entities = (Stream<Entity>) invocation.getArguments()[0]; List<Entity> entityList = entities.collect(Collectors.toList()); return entityList.size(); } }); RepositoryCollection source = mock(RepositoryCollection.class); when(source.getEntityNames()).thenReturn(entityNames); when(source.getRepository(entityName0)).thenReturn(repo0); String defaultPackage = "package"; EntityImportReport entityImportReport = vcfImporterService.doImport(source, DatabaseAction.ADD, defaultPackage); EntityImportReport expectedEntityImportReport = new EntityImportReport(); expectedEntityImportReport.addNewEntity(sampleEntityName0); expectedEntityImportReport.addEntityCount(sampleEntityName0, 4); expectedEntityImportReport.addNewEntity(entityName0); expectedEntityImportReport.addEntityCount(entityName0, entities.size()); assertEquals(entityImportReport, expectedEntityImportReport); verify(metaDataService, times(1)).createRepository(argThat(eqName(sampleEntityType0))); verify(metaDataService, times(1)).createRepository(argThat(eqName(entityType0))); verify(permissionSystemService, times(1)) .giveUserEntityPermissions(securityContext, singletonList(entityName0)); verify(permissionSystemService, times(1)) .giveUserEntityPermissions(securityContext, singletonList(sampleEntityName0)); } @Test(expectedExceptions = MolgenisDataException.class) public void doImportAlreadyExists() { String entityName0 = "entity0"; List<String> entityNames = Arrays.asList(entityName0); Repository<Entity> repo0 = mock(Repository.class); when(repo0.getName()).thenReturn(entityName0); RepositoryCollection source = mock(RepositoryCollection.class); when(source.getEntityNames()).thenReturn(entityNames); when(source.getRepository(entityName0)).thenReturn(repo0); when(dataService.hasRepository(entityName0)).thenReturn(true); String defaultPackage = "package"; vcfImporterService.doImport(source, DatabaseAction.ADD, defaultPackage); } @Test(expectedExceptions = IllegalArgumentException.class) public void doImportAddIgnoreExisting() { RepositoryCollection source = mock(RepositoryCollection.class); String defaultPackage = "package"; vcfImporterService.doImport(source, DatabaseAction.ADD_IGNORE_EXISTING, defaultPackage); } @Test(expectedExceptions = IllegalArgumentException.class) public void doImportAddUpdateExisting() { RepositoryCollection source = mock(RepositoryCollection.class); String defaultPackage = "package"; vcfImporterService.doImport(source, DatabaseAction.ADD_UPDATE_EXISTING, defaultPackage); } @Test(expectedExceptions = IllegalArgumentException.class) public void doImportUpdate() { RepositoryCollection source = mock(RepositoryCollection.class); String defaultPackage = "package"; vcfImporterService.doImport(source, DatabaseAction.UPDATE, defaultPackage); } @Test public void validateImportWithoutSamples() { // Test with multiple input repositories not possible due to // https://github.com/molgenis/molgenis/issues/4544 File file = mock(File.class); String entityName0 = "entity0"; List<String> entityNames = Arrays.asList(entityName0); String attrName0 = "attr0"; Attribute attr0 = mock(Attribute.class); when(attr0.getName()).thenReturn(attrName0); EntityType entityType0 = mock(EntityType.class); when(entityType0.getName()).thenReturn(entityName0); when(entityType0.getSimpleName()).thenReturn(entityName0); when(entityType0.getOwnAttributes()).thenReturn(singletonList(attr0)); when(entityType0.getAtomicAttributes()).thenReturn(singletonList(attr0)); when(entityType0.getOwnLookupAttributes()).thenReturn(emptyList()); Repository<Entity> repo0 = mock(Repository.class); when(repo0.getName()).thenReturn(entityName0); when(repo0.getEntityType()).thenReturn(entityType0); RepositoryCollection source = mock(RepositoryCollection.class); when(source.getEntityNames()).thenReturn(entityNames); when(source.getRepository(entityName0)).thenReturn(repo0); EntitiesValidationReport entitiesValidationReport = vcfImporterService.validateImport(file, source); assertTrue(entitiesValidationReport.valid()); assertEquals(entitiesValidationReport.getFieldsAvailable(), emptyMap()); assertEquals(entitiesValidationReport.getFieldsImportable(), singletonMap(entityName0, singletonList(attrName0))); assertEquals(entitiesValidationReport.getFieldsRequired(), emptyMap()); assertEquals(entitiesValidationReport.getFieldsUnknown(), emptyMap()); assertEquals(entitiesValidationReport.getImportOrder(), emptyList()); assertEquals(entitiesValidationReport.getPackages(), emptyList()); assertEquals(entitiesValidationReport.getSheetsImportable(), singletonMap(entityName0, Boolean.TRUE)); } @Test public void validateImportWithoutSamplesAlreadyExists() { // Test with multiple input repositories not possible due to // https://github.com/molgenis/molgenis/issues/4544 File file = mock(File.class); String entityName0 = "entity0"; List<String> entityNames = Arrays.asList(entityName0); String attrName0 = "attr0"; Attribute attr0 = mock(Attribute.class); when(attr0.getName()).thenReturn(attrName0); EntityType entityType0 = mock(EntityType.class); when(entityType0.getName()).thenReturn(entityName0); when(entityType0.getSimpleName()).thenReturn(entityName0); when(entityType0.getOwnAttributes()).thenReturn(singletonList(attr0)); when(entityType0.getAtomicAttributes()).thenReturn(singletonList(attr0)); when(entityType0.getOwnLookupAttributes()).thenReturn(emptyList()); Repository<Entity> repo0 = mock(Repository.class); when(repo0.getName()).thenReturn(entityName0); when(repo0.getEntityType()).thenReturn(entityType0); RepositoryCollection source = mock(RepositoryCollection.class); when(source.getEntityNames()).thenReturn(entityNames); when(source.getRepository(entityName0)).thenReturn(repo0); when(dataService.hasRepository(entityName0)).thenReturn(true); EntitiesValidationReport entitiesValidationReport = vcfImporterService.validateImport(file, source); assertFalse(entitiesValidationReport.valid()); assertEquals(entitiesValidationReport.getFieldsAvailable(), emptyMap()); assertEquals(entitiesValidationReport.getFieldsImportable(), singletonMap(entityName0, singletonList(attrName0))); assertEquals(entitiesValidationReport.getFieldsRequired(), emptyMap()); assertEquals(entitiesValidationReport.getFieldsUnknown(), emptyMap()); assertEquals(entitiesValidationReport.getImportOrder(), emptyList()); assertEquals(entitiesValidationReport.getPackages(), emptyList()); assertEquals(entitiesValidationReport.getSheetsImportable(), singletonMap(entityName0, Boolean.FALSE)); } @Test public void validateImportWithSamples() { // Test with multiple input repositories not possible due to // https://github.com/molgenis/molgenis/issues/4544 File file = mock(File.class); String entityName0 = "entity0"; List<String> entityNames = Arrays.asList(entityName0); String attrName0 = "attr0"; Attribute attr0 = mock(Attribute.class); when(attr0.getName()).thenReturn(attrName0); String sampleAttrName0 = "sampleAttr0"; Attribute sampleAttr0 = mock(Attribute.class); when(sampleAttr0.getName()).thenReturn(sampleAttrName0); String sampleEntityName0 = "entity0sample"; EntityType sampleEntityType0 = mock(EntityType.class); when(sampleEntityType0.getName()).thenReturn(sampleEntityName0); when(sampleEntityType0.getSimpleName()).thenReturn(sampleEntityName0); when(sampleEntityType0.getOwnAttributes()).thenReturn(emptyList()); when(sampleEntityType0.getAtomicAttributes()).thenReturn(singleton(sampleAttr0)); when(sampleEntityType0.getOwnLookupAttributes()).thenReturn(emptyList()); Attribute sampleAttr = mock(Attribute.class); when(sampleAttr.getName()).thenReturn(VcfAttributes.SAMPLES); when(sampleAttr.getRefEntity()).thenReturn(sampleEntityType0); when(sampleAttr.getDataType()).thenReturn(MREF); EntityType entityType0 = mock(EntityType.class); when(entityType0.getName()).thenReturn(entityName0); when(entityType0.getSimpleName()).thenReturn(entityName0); when(entityType0.getAttribute(VcfAttributes.SAMPLES)).thenReturn(sampleAttr); when(entityType0.getOwnAttributes()).thenReturn(singletonList(sampleAttr)); when(entityType0.getAtomicAttributes()).thenReturn(singletonList(sampleAttr)); when(entityType0.getOwnLookupAttributes()).thenReturn(emptyList()); Repository<Entity> repo0 = mock(Repository.class); when(repo0.getName()).thenReturn(entityName0); when(repo0.getEntityType()).thenReturn(entityType0); RepositoryCollection source = mock(RepositoryCollection.class); when(source.getEntityNames()).thenReturn(entityNames); when(source.getRepository(entityName0)).thenReturn(repo0); EntitiesValidationReport entitiesValidationReport = vcfImporterService.validateImport(file, source); assertTrue(entitiesValidationReport.valid()); assertEquals(entitiesValidationReport.getFieldsAvailable(), emptyMap()); Map<String, List<String>> importableFields = new HashMap<String, List<String>>(); importableFields.put(entityName0, singletonList(VcfAttributes.SAMPLES)); importableFields.put(sampleEntityName0, singletonList(sampleAttrName0)); assertEquals(entitiesValidationReport.getFieldsImportable(), importableFields); assertEquals(entitiesValidationReport.getFieldsRequired(), emptyMap()); assertEquals(entitiesValidationReport.getFieldsUnknown(), emptyMap()); assertEquals(entitiesValidationReport.getImportOrder(), emptyList()); assertEquals(entitiesValidationReport.getPackages(), emptyList()); Map<String, Boolean> sheetsImportable = new HashMap<>(); sheetsImportable.put(entityName0, Boolean.TRUE); sheetsImportable.put(sampleEntityName0, Boolean.TRUE); assertEquals(entitiesValidationReport.getSheetsImportable(), sheetsImportable); } @Test public void validateImportWithSamplesAlreadyExists() { // Test with multiple input repositories not possible due to // https://github.com/molgenis/molgenis/issues/4544 File file = mock(File.class); String entityName0 = "entity0"; List<String> entityNames = Arrays.asList(entityName0); String attrName0 = "attr0"; Attribute attr0 = mock(Attribute.class); when(attr0.getName()).thenReturn(attrName0); String sampleAttrName0 = "sampleAttr0"; Attribute sampleAttr0 = mock(Attribute.class); when(sampleAttr0.getName()).thenReturn(sampleAttrName0); String sampleEntityName0 = "entity0sample"; EntityType sampleEntityType0 = mock(EntityType.class); when(sampleEntityType0.getName()).thenReturn(sampleEntityName0); when(sampleEntityType0.getSimpleName()).thenReturn(sampleEntityName0); when(sampleEntityType0.getOwnAttributes()).thenReturn(emptyList()); when(sampleEntityType0.getAtomicAttributes()).thenReturn(singleton(sampleAttr0)); when(sampleEntityType0.getOwnLookupAttributes()).thenReturn(emptyList()); Attribute sampleAttr = mock(Attribute.class); when(sampleAttr.getName()).thenReturn(VcfAttributes.SAMPLES); when(sampleAttr.getRefEntity()).thenReturn(sampleEntityType0); when(sampleAttr.getDataType()).thenReturn(MREF); EntityType entityType0 = mock(EntityType.class); when(entityType0.getName()).thenReturn(entityName0); when(entityType0.getSimpleName()).thenReturn(entityName0); when(entityType0.getAttribute(VcfAttributes.SAMPLES)).thenReturn(sampleAttr); when(entityType0.getOwnAttributes()).thenReturn(singletonList(sampleAttr)); when(entityType0.getAtomicAttributes()).thenReturn(singletonList(sampleAttr)); when(entityType0.getOwnLookupAttributes()).thenReturn(emptyList()); Repository<Entity> repo0 = mock(Repository.class); when(repo0.getName()).thenReturn(entityName0); when(repo0.getEntityType()).thenReturn(entityType0); RepositoryCollection source = mock(RepositoryCollection.class); when(source.getEntityNames()).thenReturn(entityNames); when(source.getRepository(entityName0)).thenReturn(repo0); when(dataService.hasRepository(entityName0)).thenReturn(true); when(dataService.hasRepository(sampleEntityName0)).thenReturn(true); EntitiesValidationReport entitiesValidationReport = vcfImporterService.validateImport(file, source); assertFalse(entitiesValidationReport.valid()); assertEquals(entitiesValidationReport.getFieldsAvailable(), emptyMap()); Map<String, List<String>> importableFields = new HashMap<String, List<String>>(); importableFields.put(entityName0, singletonList(VcfAttributes.SAMPLES)); importableFields.put(sampleEntityName0, singletonList(sampleAttrName0)); assertEquals(entitiesValidationReport.getFieldsImportable(), importableFields); assertEquals(entitiesValidationReport.getFieldsRequired(), emptyMap()); assertEquals(entitiesValidationReport.getFieldsUnknown(), emptyMap()); assertEquals(entitiesValidationReport.getImportOrder(), emptyList()); assertEquals(entitiesValidationReport.getPackages(), emptyList()); Map<String, Boolean> sheetsImportable = new HashMap<>(); sheetsImportable.put(entityName0, Boolean.FALSE); sheetsImportable.put(sampleEntityName0, Boolean.FALSE); assertEquals(entitiesValidationReport.getSheetsImportable(), sheetsImportable); } @Test public void canImportVcf() { RepositoryCollection source = mock(RepositoryCollection.class); assertTrue(vcfImporterService.canImport(new File("file.vcf"), source)); } @Test public void canImportVcfGz() { RepositoryCollection source = mock(RepositoryCollection.class); assertTrue(vcfImporterService.canImport(new File("file.vcf.gz"), source)); } @Test public void canImportXls() { RepositoryCollection source = mock(RepositoryCollection.class); assertFalse(vcfImporterService.canImport(new File("file.xls"), source)); } private static Matcher<EntityType> eqName(EntityType expectedEntityType) { return new BaseMatcher<EntityType>() { @Override public boolean matches(Object item) { if (!(item instanceof EntityType)) { return false; } return ((EntityType) item).getName().equals(expectedEntityType.getName()); } @Override public void describeTo(Description description) { description.appendText("is EntityType with same name"); } }; } }