/** * Copyright (c) Codice Foundation * <p/> * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * <p/> * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. **/ package org.codice.ddf.spatial.geocoding.extract; import static org.codice.ddf.spatial.geocoding.GeoEntryExtractor.ExtractionCallback; import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import java.io.File; import java.io.FileNotFoundException; import java.util.List; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.codice.ddf.spatial.geocoding.GeoEntry; import org.codice.ddf.spatial.geocoding.GeoEntryExtractionException; import org.codice.ddf.spatial.geocoding.ProgressCallback; import org.codice.ddf.spatial.geocoding.TestBase; import org.codice.ddf.spatial.geocoding.create.GeoNamesCreator; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; public class TestGeoNamesFileExtractor extends TestBase { private static final String VALID_TEXT_FILE_PATH = TestGeoNamesFileExtractor.class.getResource("/geonames/valid.txt").getPath(); private static final String INVALID_TEXT_FILE_PATH = TestGeoNamesFileExtractor.class.getResource("/geonames/invalid.txt").getPath(); private static final String VALID_ZIP_FILE_PATH = TestGeoNamesFileExtractor.class.getResource("/geonames/valid_zip.zip").getPath(); private static final String UNSUPPORTED_FILE_PATH = TestGeoNamesFileExtractor.class.getResource("/geonames/foo.rtf").getPath(); private GeoNamesFileExtractor geoNamesFileExtractor; @Before public void setUp() { geoNamesFileExtractor = new GeoNamesFileExtractor(); geoNamesFileExtractor.setGeoEntryCreator(new GeoNamesCreator()); } private void verifyGeoEntryList(final List<GeoEntry> geoEntryList) { assertEquals(3, geoEntryList.size()); verifyGeoEntry(geoEntryList.get(0), "Kingman", 35.18944, -114.05301, "PPLA2", 28068); verifyGeoEntry(geoEntryList.get(1), "Lake Havasu City", 34.4839, -114.32245, "PPL", 52527); verifyGeoEntry(geoEntryList.get(2), "Marana", 32.43674, -111.22538, "PPL", 34961); } private void testFileExtractionAllAtOnce(final String fileLocation, final ProgressCallback mockProgressCallback) { final List<GeoEntry> geoEntryList = geoNamesFileExtractor.getGeoEntries(fileLocation, mockProgressCallback); if (mockProgressCallback != null) { verify(mockProgressCallback, atLeastOnce()).updateProgress(anyInt()); } verifyGeoEntryList(geoEntryList); } private void testFileExtractionStreaming(final String fileLocation) { final ExtractionCallback extractionCallback = mock(ExtractionCallback.class); final ArgumentCaptor<GeoEntry> geoEntryArgumentCaptor = ArgumentCaptor.forClass(GeoEntry.class); geoNamesFileExtractor.getGeoEntriesStreaming(fileLocation, extractionCallback); verify(extractionCallback, atLeastOnce()).updateProgress(anyInt()); verify(extractionCallback, times(3)).extracted(geoEntryArgumentCaptor.capture()); final List<GeoEntry> capturedGeoEntryList = geoEntryArgumentCaptor.getAllValues(); verifyGeoEntryList(capturedGeoEntryList); } @Test public void testExtractFromValidTextFileAllAtOnce() { testFileExtractionAllAtOnce(VALID_TEXT_FILE_PATH, mock(ProgressCallback.class)); } @Test public void testExtractFromValidTextFileStreaming() { testFileExtractionStreaming(VALID_TEXT_FILE_PATH); } @Test public void testExtractFromValidZipFileAllAtOnce() { testFileExtractionAllAtOnce(VALID_ZIP_FILE_PATH, null); // Delete the extracted text file. FileUtils.deleteQuietly(new File( FilenameUtils.removeExtension(VALID_ZIP_FILE_PATH) + ".txt")); } @Test public void testExtractFromValidZipFileStreaming() { testFileExtractionStreaming(VALID_ZIP_FILE_PATH); // Delete the extracted text file. FileUtils.deleteQuietly(new File( FilenameUtils.removeExtension(VALID_ZIP_FILE_PATH) + ".txt")); } @Test public void testExtractFromTextFileWrongFormat() { try { geoNamesFileExtractor.getGeoEntries(INVALID_TEXT_FILE_PATH, null); fail("Should have thrown a GeoEntryExtractionException because 'invalid.txt' is not " + "formatted in the expected way."); } catch (GeoEntryExtractionException e) { assertThat(e.getCause(), instanceOf(IndexOutOfBoundsException.class)); } } @Test public void testExtractFromNonexistentFile() { try { geoNamesFileExtractor.getGeoEntries( FilenameUtils.getFullPath(VALID_TEXT_FILE_PATH) + "fake.txt", null); fail("Should have thrown a GeoEntryExtractionException because 'fake.txt' does not " + "exist."); } catch (GeoEntryExtractionException e) { assertThat(e.getCause(), instanceOf(FileNotFoundException.class)); } } @Test(expected = GeoEntryExtractionException.class) public void testExtractFromUnsupportedFileType() { geoNamesFileExtractor.getGeoEntries(UNSUPPORTED_FILE_PATH, null); } @Test(expected = IllegalArgumentException.class) public void testNullExtractionCallback() { geoNamesFileExtractor.getGeoEntriesStreaming(VALID_TEXT_FILE_PATH, null); } }