package org.gbif.checklistbank.service.mybatis;
import org.gbif.api.model.checklistbank.NameUsage;
import org.gbif.api.model.checklistbank.NameUsageMetrics;
import org.gbif.api.model.checklistbank.ParsedName;
import org.gbif.api.model.common.paging.Pageable;
import org.gbif.api.model.common.paging.PagingConstants;
import org.gbif.api.model.common.paging.PagingRequest;
import org.gbif.api.service.checklistbank.NameUsageService;
import org.gbif.api.vocabulary.NameUsageIssue;
import org.gbif.api.vocabulary.Origin;
import org.gbif.api.vocabulary.Rank;
import org.gbif.checklistbank.model.RawUsage;
import org.gbif.checklistbank.service.mybatis.guice.InternalChecklistBankServiceMyBatisModule;
import java.net.URI;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
import com.google.common.base.Joiner;
import com.zaxxer.hikari.HikariDataSource;
import org.gbif.checklistbank.service.mybatis.postgres.ClbDbTestRule;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class NameUsageServiceMyBatisIT extends MyBatisServiceITBase<NameUsageService> {
public NameUsageServiceMyBatisIT() {
super(NameUsageService.class);
}
private final int NOT_FOUND_KEY = -10;
@Test
public void testGet() {
final NameUsage rodentia = service.get(100000004, Locale.UK);
final NameUsageMetrics rodentiaM = service.getMetrics(100000004);
assertNotNull(rodentia);
assertEquals((Integer) 10, rodentia.getNubKey());
assertFalse(rodentia.isSynonym());
assertEquals("1000", rodentia.getTaxonID());
assertEquals("Rodentia", rodentia.getCanonicalName());
assertEquals("Rodentia Bowdich, 1821", rodentia.getScientificName());
assertEquals("Bowdich, 1821", rodentia.getAuthorship());
assertEquals(Rank.ORDER, rodentia.getRank());
assertEquals((Integer) 100000003, rodentia.getParentKey());
assertEquals("Animalia", rodentia.getKingdom());
assertEquals((Integer) 100000001, rodentia.getKingdomKey());
assertEquals("Chordata", rodentia.getPhylum());
assertEquals((Integer) 100000002, rodentia.getPhylumKey());
assertEquals(0, rodentiaM.getNumPhylum());
assertEquals("Mammalia", rodentia.getClazz());
assertEquals((Integer) 100000003, rodentia.getClassKey());
assertEquals(0, rodentiaM.getNumClass());
assertEquals(1, rodentiaM.getNumOrder());
assertEquals(1, rodentiaM.getNumFamily());
assertEquals(2, rodentiaM.getNumGenus());
assertEquals(3, rodentiaM.getNumSpecies());
assertEquals(8, rodentiaM.getNumSynonyms());
assertEquals(1, rodentiaM.getNumChildren());
assertEquals(24, rodentia.getNumDescendants());
assertEquals(Origin.SOURCE, rodentia.getOrigin());
assertEquals(ClbDbTestRule.SQUIRRELS_DATASET_KEY, rodentia.getDatasetKey());
assertNull(rodentia.getPublishedIn());
assertEquals("1000", rodentia.getTaxonID());
NameUsage squirrel = service.get(100000025, Locale.UK);
final NameUsageMetrics squirrelM = service.getMetrics(100000025);
assertNotNull(squirrel);
assertNull(squirrel.getNubKey());
assertFalse(squirrel.isSynonym());
assertEquals("Sciurus vulgaris", squirrel.getCanonicalName());
assertEquals("Sciurus vulgaris Linnaeus, 1758", squirrel.getScientificName());
assertEquals("Linnaeus, 1758", squirrel.getAuthorship());
assertEquals("Eurasian Red Squirrel", squirrel.getVernacularName());
assertEquals(Rank.SPECIES, squirrel.getRank());
assertEquals((Integer) 100000024, squirrel.getParentKey());
assertEquals("Animalia", squirrel.getKingdom());
assertEquals((Integer) 100000001, squirrel.getKingdomKey());
assertEquals("Chordata", squirrel.getPhylum());
assertEquals((Integer) 100000002, squirrel.getPhylumKey());
assertEquals(0, squirrelM.getNumPhylum());
assertEquals("Mammalia", squirrel.getClazz());
assertEquals((Integer) 100000003, squirrel.getClassKey());
assertEquals(0, squirrelM.getNumClass());
assertEquals("Rodentia", squirrel.getOrder());
assertEquals((Integer) 100000004, squirrel.getOrderKey());
assertEquals(0, squirrelM.getNumOrder());
assertEquals("Sciuridae", squirrel.getFamily());
assertEquals((Integer) 100000005, squirrel.getFamilyKey());
assertEquals(0, squirrelM.getNumFamily());
assertEquals("Sciurus", squirrel.getGenus());
assertEquals((Integer) 100000011, squirrel.getGenusKey());
assertEquals(0, squirrelM.getNumGenus());
assertEquals(1, squirrelM.getNumSpecies());
assertEquals(9, squirrelM.getNumChildren());
assertEquals(4, squirrelM.getNumSynonyms());
assertEquals(ClbDbTestRule.SQUIRRELS_DATASET_KEY, squirrel.getDatasetKey());
assertEquals("Syst. Nat. , 10th ed. vol. 1 p. 63", squirrel.getPublishedIn());
assertEquals("2010030", squirrel.getTaxonID());
// TEST VERNACULAR
squirrel = service.get(100000040, null);
assertNull(squirrel.getVernacularName());
squirrel = service.get(100000040, Locale.ENGLISH);
assertEquals("Caucasian Squirrel", squirrel.getVernacularName());
squirrel = service.get(100000040, Locale.GERMANY);
assertEquals("Kaukasischen Eichhörnchen", squirrel.getVernacularName());
// TEST non existing language VERNACULAR
squirrel = service.get(100000040, Locale.CHINESE);
assertNull(squirrel.getVernacularName());
// TEST MULTIPLE IDENTIFIERS
squirrel = service.get(100000007, Locale.GERMANY);
assertEquals("6905528", squirrel.getTaxonID());
assertEquals(URI.create("http://www.catalogueoflife.org/details/species/id/6905528"), squirrel.getReferences());
// TEST SYNONYM
NameUsage syn = service.get(100000027, Locale.FRENCH);
assertNotNull(syn);
assertTrue(syn.isSynonym());
assertEquals("Sciurus nadymensis", syn.getCanonicalName());
assertEquals("Sciurus nadymensis Serebrennikov, 1928", syn.getScientificName());
assertNull(syn.getVernacularName());
assertEquals(Rank.SPECIES, syn.getRank());
assertEquals((Integer) 100000024, syn.getParentKey());
assertEquals((Integer) 100000025, syn.getAcceptedKey());
assertEquals("Sciurus vulgaris Linnaeus, 1758", syn.getAccepted());
assertFalse(syn.isProParte());
}
@Test
public void testArraySet() {
// test nomenclatoral status set
NameUsage syn = service.get(100000026, Locale.FRENCH);
assertEquals(2, syn.getNomenclaturalStatus().size());
}
@Test
public void testGetNotFound() {
assertNull(service.get(NOT_FOUND_KEY, Locale.UK));
}
@Test
public void testGetParsedName() {
final ParsedName rodentia = service.getParsedName(100000004);
assertNotNull(rodentia);
assertEquals("Rodentia", rodentia.getGenusOrAbove());
assertEquals("Bowdich", rodentia.getAuthorship());
assertEquals("1821", rodentia.getYear());
assertEquals(Rank.ORDER, rodentia.getRank());
}
@Test
public void testGetParsedNameNotFound() {
assertNull(service.getParsedName(NOT_FOUND_KEY));
}
@Test
public void testList() {
List<NameUsage> usages = service.list(Locale.UK, null, null, null).getResults();
assertEquals(PagingConstants.DEFAULT_PARAM_LIMIT, usages.size());
// test paging
Pageable page = new PagingRequest(1l, 1);
usages = service.list(Locale.UK, null, null, page).getResults();
assertEquals(1, usages.size());
NameUsage u1 = usages.get(0);
page = new PagingRequest(0l, 2);
usages = service.list(Locale.UK, null, null, page).getResults();
assertEquals(2, usages.size());
assertEquals(u1, usages.get(1));
// test by source id
usages = service.list(Locale.UK, null, "1", null).getResults();
assertEquals(1, usages.size());
assertEquals((Integer) 100000001, usages.get(0).getKey());
// test by checklist key
usages = service.list(Locale.UK, UUID.fromString("d7dddbf4-2cf0-4f39-9b2a-bb099caae36c"), null, null)
.getResults();
assertEquals(2, usages.size());
// test combined
usages =
service.list(Locale.UK, ClbDbTestRule.SQUIRRELS_DATASET_KEY, "1", null).getResults();
assertEquals(1, usages.size());
assertEquals((Integer) 100000001, usages.get(0).getKey());
}
@Test
public void testByTaxonId() {
List<NameUsage> usages = service.list(Locale.UK, ClbDbTestRule.SQUIRRELS_DATASET_KEY, "100000", null).getResults();
assertEquals(1, usages.size());
assertEquals(service.get(100000006, Locale.UK), usages.get(0));
}
@Test
public void testListRelated() {
List<NameUsage> usages = service.listRelated(1, Locale.UK, null).getResults();
;
assertEquals(1, usages.size());
usages = service.listRelated(1, Locale.UK, null, ClbDbTestRule.SQUIRRELS_DATASET_KEY).getResults();
assertEquals(1, usages.size());
usages = service.listRelated(1, Locale.UK, null, ClbDbTestRule.SQUIRRELS_DATASET_KEY,
UUID.fromString("109aea14-c252-4a85-96e2-f5f4d5d088f5")).getResults();
assertEquals(1, usages.size());
usages = service.listRelated(1, Locale.UK, null, UUID.fromString("109aea14-c252-4a85-96e2-f5f4d5d088ff")).getResults();
assertEquals(0, usages.size());
}
@Test
public void testListCombinations() {
List<NameUsage> usages = service.listCombinations(1, Locale.UK);
assertEquals(0, usages.size());
usages = service.listCombinations(100000025, Locale.UK);
assertEquals(2, usages.size());
}
@Test
public void testListRelatedNotFound() {
assertTrue(service.listRelated(NOT_FOUND_KEY, Locale.UK, null).getResults().isEmpty());
}
@Test
public void testListChildren() {
List<NameUsage> usages = service.listChildren(100000025, Locale.UK, null).getResults();
assertEquals(9, usages.size());
// assert we start with highest ranks, then lower ones
assertEquals(Rank.SUBSPECIES, usages.get(0).getRank());
assertEquals(Rank.SUBSPECIES, usages.get(1).getRank());
assertEquals(Rank.VARIETY, usages.get(7).getRank());
assertEquals(Rank.VARIETY, usages.get(8).getRank());
// test paging
Pageable page = new PagingRequest(3, 2);
usages = service.listChildren(100000025, Locale.UK, page).getResults();
assertEquals(2, usages.size());
page = new PagingRequest(2, 5);
List<NameUsage> usages2 = service.listChildren(100000025, Locale.UK, page).getResults();
assertEquals(5, usages2.size());
assertEquals(usages.get(0), usages2.get(1));
assertEquals(usages.get(1), usages2.get(2));
}
@Test
public void testListChildrenNotFound() {
assertTrue(service.listChildren(NOT_FOUND_KEY, Locale.UK, null).getResults().isEmpty());
}
@Test
public void testListRoot() {
List<NameUsage> usages = service.listRoot(ClbDbTestRule.SQUIRRELS_DATASET_KEY, Locale.UK, null).getResults();
assertEquals(1, usages.size());
// test paging
Pageable page = new PagingRequest(1l, 1);
usages = service.listRoot(ClbDbTestRule.SQUIRRELS_DATASET_KEY, Locale.UK, page).getResults();
assertEquals(0, usages.size());
page = new PagingRequest(0l, 2);
usages = service.listRoot(ClbDbTestRule.SQUIRRELS_DATASET_KEY, Locale.UK, page).getResults();
assertEquals(1, usages.size());
}
@Test
public void testListSynonyms() {
List<NameUsage> usages = service.listSynonyms(100000025, Locale.UK, null).getResults();
assertEquals(4, usages.size());
// test paging
Pageable page = new PagingRequest(0, 2);
usages = service.listSynonyms(100000025, Locale.UK, page).getResults();
assertEquals(2, usages.size());
page = new PagingRequest(1, 2);
List<NameUsage> usages2 = service.listSynonyms(100000025, Locale.UK, page).getResults();
assertEquals(2, usages2.size());
assertEquals(usages.get(1), usages2.get(0));
}
@Test
public void testListSynonymsNotFound() {
assertTrue(service.listSynonyms(NOT_FOUND_KEY, Locale.UK, null).getResults().isEmpty());
}
@Test
public void testVerbatim() {
// even though the record exists the verbatim smile data is empty, so null here
assertNull(service.getVerbatim(100000011));
assertNull(service.getVerbatim(NOT_FOUND_KEY));
}
@Test
public void testUsageMetrics() {
NameUsageMetrics m = service.getMetrics(100000011);
assertNotNull(m);
assertEquals((Integer) 100000011, m.getKey());
assertEquals(2, m.getNumChildren());
assertEquals(12, m.getNumSynonyms());
assertEquals(1, m.getNumGenus());
assertEquals(2, m.getNumSubgenus());
assertEquals(2, m.getNumSpecies());
// not set in dbSetup file
assertEquals(3, m.getNumDescendants());
assertEquals(0, m.getNumFamily());
assertNull(service.getMetrics(NOT_FOUND_KEY));
}
/**
* http://dev.gbif.org/issues/browse/POR-3032
*/
@Test
public void testUsageIssues() {
NameUsage u = service.get(100000040, null);
assertNotNull(u);
assertEquals(1, u.getIssues().size());
EnumSet expected = EnumSet.of(NameUsageIssue.RANK_INVALID);
assertEquals(expected, u.getIssues());
Joiner j = Joiner.on(",").skipNulls();
for (int x = 0; x < 10; x++) {
u = service.get(100000040, null);
assertEquals("Call "+x+" should be correct", expected, u.getIssues());
}
}
/**
* Prepared statements in postgres jdbc have a bug when caching text[] array types.
* This test shows it and we circumvent this behavior by telling mybatis not to cache results.
*
* http://dev.gbif.org/issues/browse/POR-3032
*
* https://github.com/pgjdbc/pgjdbc/issues/517
*/
@Test
public void testUsageIssuesJdbc() throws Exception {
HikariDataSource ds = (HikariDataSource) getInstance(InternalChecklistBankServiceMyBatisModule.DATASOURCE_KEY);
try (Connection cn = ds.getConnection()) {
PreparedStatement st = cn.prepareStatement("select issues from name_usage where id=?");
for (int x = 0; x < 10; x++) {
st.setInt(1, 100000040);
st.execute();
ResultSet rs = st.getResultSet();
rs.next();
System.out.println(rs.getString(1));
}
} finally {
ds.close();
}
}
@Test
public void insertRaw() {
final int key = 100000001;
final String data = "xeghwax542tgld@";
RawUsage raw = new RawUsage();
raw.setUsageKey(key);
raw.setDatasetKey(ClbDbTestRule.SQUIRRELS_DATASET_KEY);
// date is null in dataset_metrics table
//raw.setLastCrawled(new Date());
raw.setJson(data);
((NameUsageServiceMyBatis) service).insertRaw(raw);
RawUsage raw2 = ((NameUsageServiceMyBatis) service).getRaw(key);
Assert.assertEquals(raw, raw2);
}
}