package eu.balticdiversity.feedreaders;
import fi.luomus.commons.reporting.ErrorReporingToSystemErr;
import org.junit.Test;
import java.io.IOException;
import java.net.URI;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.Assert.*;
public class DocumentServiceTest {
private final String SINGLE_ENTRY = "<SimpleDarwinRecordSet xmlns:dc=\"http://purl.org/dc/terms/\" xmlns:dwc=\"http://rs.tdwg.org/dwc/terms/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
"<SimpleDarwinRecord>\n" +
"<dwc:occurrenceID>52685402</dwc:occurrenceID>\n" +
"<dc:modified>2011-12-12T10:19:00Z</dc:modified>\n" +
"<dwc:institutionCode>NRM</dwc:institutionCode>\n" +
"<dwc:collectionCode>RingedBirds</dwc:collectionCode>\n" +
"<dwc:datasetName>NRM Bird ringing</dwc:datasetName>\n" +
"<dwc:basisOfRecord>O</dwc:basisOfRecord>\n" +
"<dwc:catalogNumber>926501</dwc:catalogNumber>\n" +
"<dwc:occurrenceRemarks></dwc:occurrenceRemarks>\n" +
"<dwc:individualCount>1</dwc:individualCount>\n" +
"<dwc:associatedReferences>http://www.gbif.se/occurrence/52685402</dwc:associatedReferences>\n" +
"<dwc:eventDate>2002-09-09</dwc:eventDate>\n" +
"<dwc:year>2002</dwc:year>\n" +
"<dwc:month>9</dwc:month>\n" +
"<dwc:day>9</dwc:day>\n" +
"<dwc:continent>EUROPE</dwc:continent>\n" +
"<dwc:country>SWEDEN</dwc:country>\n" +
"<dwc:stateProvince> Blekinge</dwc:stateProvince>\n" +
"<dwc:locality>TORHAMN</dwc:locality>\n" +
"<dwc:maximumDepthInMeters>0</dwc:maximumDepthInMeters>\n" +
"<dwc:decimalLatitude>56.0833</dwc:decimalLatitude>\n" +
"<dwc:decimalLongitude>15.8500</dwc:decimalLongitude>\n" +
"<dwc:dateIdentified>2002-09-09</dwc:dateIdentified>\n" +
"<dwc:scientificName>Sylvia atricapilla</dwc:scientificName>\n" +
"<dwc:kingdom>Animalia</dwc:kingdom>\n" +
"<dwc:phylum>Chordata</dwc:phylum>\n" +
"<dwc:class>Aves</dwc:class>\n" +
"<dwc:genus>Sylvia</dwc:genus>\n" +
"<dwc:specificEpithet>atricapilla</dwc:specificEpithet>\n" +
"</SimpleDarwinRecord>\n" +
"</SimpleDarwinRecordSet>";
@Test
public void testStartStop() throws Exception {
final AtomicBoolean called = new AtomicBoolean(false);
DocumentQueueService service = new DocumentQueueService(null, null, new ErrorReporingToSystemErr()) {
@Override
public void saveDocuments() {
called.set(true);
}
};
Thread.sleep(100);
assertFalse(service.isRunning());
assertFalse(called.get());
service.start();
Thread.sleep(100);
assertTrue(service.isRunning());
assertTrue(called.get());
service.stop();
Thread.sleep(100);
assertFalse(service.isRunning());
}
@Test
public void testEmptySaveDocuments() throws Exception {
final List<FeedEntry> documentQueue = new ArrayList<FeedEntry>();
MockDAO dao = new MockDAO(documentQueue);
MockFeedReaderClient feedReaderClient = new MockFeedReaderClient(documentQueue);
DocumentQueueService service = new DocumentQueueService(dao, feedReaderClient, new ErrorReporingToSystemErr());
service.saveDocuments();
assertEquals(0, documentQueue.size());
assertEquals(0, dao.savedDocuments.size());
}
@Test
public void testSaveDocument() throws Exception {
final List<FeedEntry> documentQueue = new ArrayList<FeedEntry>();
documentQueue.add(new FeedEntry(new URI("http://www.foo.com"), "id", 1));
MockDAO dao = new MockDAO(documentQueue);
MockFeedReaderClient feedReaderClient = new MockFeedReaderClient(documentQueue);
DocumentQueueService service = new DocumentQueueService(dao, feedReaderClient, new ErrorReporingToSystemErr());
service.saveDocuments();
assertEquals(0, dao.getDocumentQueue(50).size());
assertEquals(1, dao.savedDocuments.size());
assertEquals(SINGLE_ENTRY, dao.savedDocuments.get(0));
}
@Test
public void testSaveDocuments() throws Exception {
final List<FeedEntry> documentQueue = new ArrayList<FeedEntry>();
for (int i = 0; i < DocumentQueueService.DOCUMENTS_PER_CYCLE; i++) {
documentQueue.add(new FeedEntry(new URI("http://www.foo.com/" + i), "id", 1));
}
MockDAO dao = new MockDAO(documentQueue);
MockFeedReaderClient feedReaderClient = new MockFeedReaderClient(documentQueue);
DocumentQueueService service = new DocumentQueueService(dao, feedReaderClient, new ErrorReporingToSystemErr());
service.saveDocuments();
assertEquals(0, dao.getDocumentQueue(50).size());
assertEquals(DocumentQueueService.DOCUMENTS_PER_CYCLE, dao.savedDocuments.size());
}
@Test
public void testSaveMoreThanRoundDocuments() throws Exception {
final List<FeedEntry> documentQueue = new ArrayList<FeedEntry>();
for (int i = 0; i < DocumentQueueService.DOCUMENTS_PER_CYCLE + 1; i++) {
documentQueue.add(new FeedEntry(new URI("http://www.foo.com/" + i), "id", 1));
}
MockDAO dao = new MockDAO(documentQueue);
MockFeedReaderClient feedReaderClient = new MockFeedReaderClient(documentQueue);
DocumentQueueService service = new DocumentQueueService(dao, feedReaderClient, new ErrorReporingToSystemErr());
service.saveDocuments();
assertEquals(1, dao.getDocumentQueue(50).size());
assertEquals(DocumentQueueService.DOCUMENTS_PER_CYCLE, dao.savedDocuments.size());
service.saveDocuments();
assertEquals(0, dao.getDocumentQueue(50).size());
assertEquals(DocumentQueueService.DOCUMENTS_PER_CYCLE + 1, dao.savedDocuments.size());
}
public class MockDAO extends DocumentQueueServiceDAO {
public final List<DBFeedEntry> documentQueue;
public final List<String> savedDocuments = new ArrayList<String>();
public MockDAO(List<FeedEntry> documentQueue) {
super(null);
this.documentQueue = new ArrayList<DBFeedEntry>();
int i = 0;
for (FeedEntry feedEntry : documentQueue) {
DBFeedEntry dbFeedEntry = new DBFeedEntry();
dbFeedEntry.setId(i++);
dbFeedEntry.setDocumentId(feedEntry.getDocumentId());
dbFeedEntry.setUri(feedEntry.getUri());
dbFeedEntry.setSourceID(feedEntry.getSourceID());
this.documentQueue.add(dbFeedEntry);
}
}
@Override
public List<DBFeedEntry> getDocumentQueue(int limit) {
return new ArrayList<DBFeedEntry>(documentQueue).subList(0, Math.min(documentQueue.size(), limit));
}
@Override
public void saveDocumentAndRemoveFromQueue(String feedDocument, DBFeedEntry documentUri) throws SQLException {
savedDocuments.add(feedDocument);
DBFeedEntry deletable = null;
for (DBFeedEntry entry : this.documentQueue) {
if (entry.getId().equals(documentUri.getId())) {
deletable = entry;
break;
}
}
if (!this.documentQueue.remove(deletable)) {
throw new RuntimeException("tried to delete a non-existent queue entry");
}
}
}
public class MockFeedReaderClient implements FeedReaderClient {
private final List<FeedEntry> queue;
public MockFeedReaderClient(List<FeedEntry> queue) {
this.queue = queue;
}
@Override
public List<FeedEntryWithSeqID> getFeedEntriesFromSeq(URI uri, long seqId, int limit) throws FeedReaderClientException {
return null;
}
@Override
public List<FeedEntryWithSeqID> getFeedEntriesSinceTimestamp(URI uri, long seqId, int limit) throws FeedReaderClientException {
return null;
}
@Override
public String getFeedDocument(URI uri) throws FeedReaderClientException {
for (FeedEntry uriWithSourceID : queue) {
if (uriWithSourceID.getUri().equals(uri)) {
return SINGLE_ENTRY;
}
}
throw new FeedReaderClientException("invalid uri");
}
@Override
public void close() throws IOException {
}
}
}