package org.molgenis.data.semanticsearch.service.impl;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import org.mockito.ArgumentCaptor;
import org.molgenis.data.DataService;
import org.molgenis.data.Entity;
import org.molgenis.data.meta.model.*;
import org.molgenis.data.meta.model.Package;
import org.molgenis.data.populate.IdGenerator;
import org.molgenis.data.semantic.Relation;
import org.molgenis.data.semantic.SemanticTag;
import org.molgenis.data.semanticsearch.repository.TagRepository;
import org.molgenis.data.semanticsearch.semantic.OntologyTag;
import org.molgenis.ontology.core.model.Ontology;
import org.molgenis.ontology.core.model.OntologyTerm;
import org.molgenis.ontology.core.service.OntologyService;
import org.molgenis.test.data.AbstractMolgenisSpringTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.util.Map;
import static java.util.Arrays.asList;
import static java.util.Collections.singleton;
import static java.util.Collections.singletonList;
import static org.mockito.ArgumentCaptor.forClass;
import static org.mockito.Mockito.*;
import static org.molgenis.data.meta.model.AttributeMetadata.ATTRIBUTE_META_DATA;
import static org.molgenis.data.meta.model.EntityTypeMetadata.ATTRIBUTES;
import static org.molgenis.data.meta.model.EntityTypeMetadata.ENTITY_TYPE_META_DATA;
import static org.molgenis.data.meta.model.PackageMetadata.PACKAGE;
import static org.testng.Assert.assertEquals;
@WebAppConfiguration
@ContextConfiguration(classes = OntologyTagServiceTest.Config.class)
public class OntologyTagServiceTest extends AbstractMolgenisSpringTest
{
private OntologyTagServiceImpl ontologyTagService;
@Autowired
private TagRepository tagRepository;
@Autowired
private OntologyService ontologyService;
@Autowired
private DataService dataService;
@Autowired
private TagMetadata tagMetadata;
@Autowired
private TagFactory tagFactory;
@Autowired
private EntityTypeFactory entityTypeFactory;
@Autowired
private AttributeFactory attrFactory;
@Autowired
private PackageFactory packageFactory;
private Tag chromosomeNameTagEntity;
private Tag geneAnnotationTagEntity;
private final Relation instanceOf = Relation.valueOf("instanceOf");
private static final Ontology EDAM_ONTOLOGY = Ontology
.create("EDAM", "http://edamontology.org", "The EDAM ontology.");
private static final OntologyTerm CHROMOSOME_NAME_ONTOLOGY_TERM = OntologyTerm
.create("http://edamontology.org/data_0987", "Chromosome name", "Name of a chromosome.");
private static final OntologyTerm GENE_ANNOTATION_ONTOLOGY_TERM = OntologyTerm
.create("http://edamontology.org/data_0919", "Gene annotation (chromosome)",
"This includes basic information. e.g. chromosome number...");
@BeforeMethod
public void beforeMethod()
{
reset(dataService);
chromosomeNameTagEntity = tagFactory.create();
chromosomeNameTagEntity.set(TagMetadata.ID, "1234");
chromosomeNameTagEntity.set(TagMetadata.LABEL, "Chromosome name");
chromosomeNameTagEntity.set(TagMetadata.OBJECT_IRI, "http://edamontology.org/data_0987");
chromosomeNameTagEntity.set(TagMetadata.RELATION_IRI, instanceOf.getIRI());
chromosomeNameTagEntity.set(TagMetadata.RELATION_LABEL, instanceOf.getLabel());
chromosomeNameTagEntity.set(TagMetadata.CODE_SYSTEM, "http://edamontology.org");
geneAnnotationTagEntity = tagFactory.create();
geneAnnotationTagEntity.set(TagMetadata.ID, "4321");
geneAnnotationTagEntity.set(TagMetadata.LABEL, "Gene annotation (chromosome)");
geneAnnotationTagEntity.set(TagMetadata.OBJECT_IRI, "http://edamontology.org/data_0919");
geneAnnotationTagEntity.set(TagMetadata.RELATION_IRI, instanceOf.getIRI());
geneAnnotationTagEntity.set(TagMetadata.RELATION_LABEL, instanceOf.getLabel());
geneAnnotationTagEntity.set(TagMetadata.CODE_SYSTEM, "http://edamontology.org");
IdGenerator idGenerator = mock(IdGenerator.class);
ontologyTagService = new OntologyTagServiceImpl(dataService, ontologyService, tagRepository, idGenerator,
tagMetadata);
}
@Test
public void testgetTagsForAttribute()
{
EntityType emd = entityTypeFactory.create().setName("org.molgenis.SNP");
Attribute attribute = attrFactory.create().setName("Chr");
Relation instanceOf = Relation.valueOf("instanceOf");
Attribute attributeEntity = attrFactory.create();
attributeEntity.setTags(asList(chromosomeNameTagEntity, geneAnnotationTagEntity));
attributeEntity.set(AttributeMetadata.NAME, "Chr");
EntityType EntityTypeEntity = entityTypeFactory.create();
EntityTypeEntity.setOwnAllAttributes(singleton(attributeEntity));
when(dataService.findOneById(ENTITY_TYPE_META_DATA, "org.molgenis.SNP")).thenReturn(EntityTypeEntity);
Ontology edamOntology = Ontology.create("EDAM", "http://edamontology.org", "The EDAM ontology.");
OntologyTerm chromosomeName = OntologyTerm
.create("http://edamontology.org/data_0987", "Chromosome name", "Name of a chromosome.");
OntologyTerm geneAnnotation = OntologyTerm
.create("http://edamontology.org/data_0919", "Gene annotation (chromosome)",
"This includes basic information. e.g. chromosome number...");
when(ontologyService.getOntology("http://edamontology.org")).thenReturn(edamOntology);
when(ontologyService.getOntologyTerm("http://edamontology.org/data_0987")).thenReturn(chromosomeName);
when(ontologyService.getOntologyTerm("http://edamontology.org/data_0919")).thenReturn(geneAnnotation);
Multimap<Relation, OntologyTerm> expected = LinkedHashMultimap.create();
expected.put(instanceOf, chromosomeName);
expected.put(instanceOf, geneAnnotation);
assertEquals(ontologyTagService.getTagsForAttribute(emd, attribute), expected);
}
@Test
public void testGetTagEntity()
{
Tag expected = tagFactory.create();
expected.set(TagMetadata.ID, "1233");
expected.set(TagMetadata.OBJECT_IRI, "http://edamontology.org/data_3031");
expected.set(TagMetadata.LABEL, "Core data");
expected.set(TagMetadata.RELATION_IRI, "http://molgenis.org/biobankconnect/instanceOf");
expected.set(TagMetadata.RELATION_LABEL, "instanceOf");
expected.set(TagMetadata.CODE_SYSTEM, "http://edamontology.org");
OntologyTerm coreData = mock(OntologyTerm.class);
when(coreData.getIRI()).thenReturn("http://edamontology.org/data_3031");
when(coreData.getLabel()).thenReturn("Core data");
Ontology edamOntology = mock(Ontology.class);
when(edamOntology.getIRI()).thenReturn("http://edamontology.org");
SemanticTag<Object, OntologyTerm, Ontology> tag = new SemanticTag<>("1233", null, Relation.instanceOf, coreData,
edamOntology);
when(tagRepository.getTagEntity("http://edamontology.org/data_3031", "Core data", Relation.instanceOf,
"http://edamontology.org")).thenReturn(expected);
assertEquals(ontologyTagService.getTagEntity(tag), expected);
}
@Test
public void testAddAttributeTag()
{
EntityType emd = entityTypeFactory.create().setName("org.molgenis.SNP");
Attribute attribute = attrFactory.create().setName("Chr");
when(ontologyService.getOntology("http://edamontology.org")).thenReturn(EDAM_ONTOLOGY);
when(ontologyService.getOntologyTerm("http://edamontology.org/data_0987"))
.thenReturn(CHROMOSOME_NAME_ONTOLOGY_TERM);
Attribute attributeEntity = attrFactory.create();
attributeEntity.setTags(singletonList(geneAnnotationTagEntity));
attributeEntity.setName("Chr");
SemanticTag<Attribute, OntologyTerm, Ontology> chromosomeTag = new SemanticTag<>("1233", attribute, instanceOf,
CHROMOSOME_NAME_ONTOLOGY_TERM, EDAM_ONTOLOGY);
EntityType EntityTypeEntity = entityTypeFactory.create();
EntityTypeEntity.setOwnAllAttributes(singleton(attributeEntity));
when(dataService.findOneById(ENTITY_TYPE_META_DATA, "org.molgenis.SNP")).thenReturn(EntityTypeEntity);
when(tagRepository.getTagEntity("http://edamontology.org/data_0987", "Chromosome name", instanceOf,
"http://edamontology.org")).thenReturn(chromosomeNameTagEntity);
ontologyTagService.addAttributeTag(emd, chromosomeTag);
ArgumentCaptor<Attribute> captor = forClass(Attribute.class);
verify(dataService, times(1)).update(eq(ATTRIBUTE_META_DATA), captor.capture());
assertEquals(captor.getValue().getName(), "Chr");
assertEquals(captor.getValue().getTags(), asList(geneAnnotationTagEntity, chromosomeNameTagEntity));
}
@Test
public void testRemoveAttributeTag()
{
EntityType emd = entityTypeFactory.create().setName("org.molgenis.SNP");
Attribute attribute = attrFactory.create().setName("Chr");
Attribute attributeEntity = attrFactory.create();
attributeEntity.setTags(asList(chromosomeNameTagEntity, geneAnnotationTagEntity));
attributeEntity.setName("Chr");
EntityType EntityTypeEntity = entityTypeFactory.create();
EntityTypeEntity.setOwnAllAttributes(singleton(attributeEntity));
when(dataService.findOneById(ENTITY_TYPE_META_DATA, "org.molgenis.SNP")).thenReturn(EntityTypeEntity);
SemanticTag<Attribute, OntologyTerm, Ontology> geneAnnotationTag = new SemanticTag<>("4321", attribute,
instanceOf, GENE_ANNOTATION_ONTOLOGY_TERM, EDAM_ONTOLOGY);
ontologyTagService.removeAttributeTag(emd, geneAnnotationTag);
ArgumentCaptor<Attribute> captor = forClass(Attribute.class);
verify(dataService, times(1)).update(eq(ATTRIBUTE_META_DATA), captor.capture());
assertEquals(captor.getValue().getTags(), asList(chromosomeNameTagEntity, geneAnnotationTagEntity));
}
@Test
public void testgetTagsForPackage()
{
Package p = packageFactory.create("test", "desc");
Package pack = packageFactory.create();
pack.setName("test");
pack.setSimpleName("test");
pack.setTags(singletonList(chromosomeNameTagEntity));
when(dataService.findOneById(PACKAGE, "test")).thenReturn(pack);
assertEquals(ontologyTagService.getTagsForPackage(p), singletonList(
new SemanticTag<>("1234", p, Relation.forIRI("http://molgenis.org/biobankconnect/instanceOf"),
OntologyTerm.create("http://edamontology.org/data_0987", "Chromosome name",
"Name of a chromosome."),
Ontology.create("EDAM", "http://edamontology.org", "The EDAM ontology."))));
}
@Test
public void testRemoveAllTagsFromEntity()
{
// FIXME This does not make sense...
EntityType emd = entityTypeFactory.create().setName("test");
Attribute amd = attrFactory.create().setName("Chr");
emd.addAttribute(amd);
when(dataService.getEntityType("test")).thenReturn(emd);
Entity entityTypeEntity = mock(Entity.class);
Entity att = mock(Entity.class);
when(entityTypeEntity.getEntities(ATTRIBUTES)).thenReturn(singletonList(att));
when(att.getString(AttributeMetadata.NAME)).thenReturn("Chr");
when(dataService.findOneById(ENTITY_TYPE_META_DATA, "test")).thenReturn(entityTypeEntity);
ontologyTagService.removeAllTagsFromEntity("test");
verify(dataService).update(ENTITY_TYPE_META_DATA, entityTypeEntity);
}
@Test
public void testTagAttributesInEntity()
{
Map<String, OntologyTag> attributeTagMap = Maps.newHashMap();
Map<Attribute, OntologyTerm> tags = Maps.newHashMap();
EntityType emd = entityTypeFactory.create().setName("org.molgenis.SNP");
Attribute attribute = attrFactory.create().setName("Chr");
when(ontologyService.getOntology("http://edamontology.org")).thenReturn(EDAM_ONTOLOGY);
when(ontologyService.getOntologyTerm("http://edamontology.org/data_0987"))
.thenReturn(CHROMOSOME_NAME_ONTOLOGY_TERM);
Attribute attributeEntity = attrFactory.create();
attributeEntity.setTags(singletonList(geneAnnotationTagEntity));
attributeEntity.setName("Chr");
SemanticTag<Attribute, OntologyTerm, Ontology> chromosomeTag = new SemanticTag<>("1233", attribute, instanceOf,
CHROMOSOME_NAME_ONTOLOGY_TERM, EDAM_ONTOLOGY);
EntityType EntityTypeEntity = entityTypeFactory.create();
EntityTypeEntity.setOwnAllAttributes(singleton(attributeEntity));
when(dataService.findOneById(ENTITY_TYPE_META_DATA, "org.molgenis.SNP")).thenReturn(EntityTypeEntity);
when(tagRepository.getTagEntity("http://edamontology.org/data_0987", "Chromosome name", instanceOf,
"http://edamontology.org")).thenReturn(chromosomeNameTagEntity);
ontologyTagService.addAttributeTag(emd, chromosomeTag);
Attribute updatedEntity = attrFactory.create();
updatedEntity.setTags(asList(geneAnnotationTagEntity, chromosomeNameTagEntity));
updatedEntity.setName("Chr");
assertEquals(ontologyTagService.tagAttributesInEntity("test", tags), attributeTagMap);
}
@Configuration
public static class Config
{
@Bean
DataService dataService()
{
return mock(DataService.class);
}
@Bean
OntologyService ontologyService()
{
return mock(OntologyService.class);
}
@Bean
TagRepository tagRepository()
{
return mock(TagRepository.class);
}
}
}