package de.blau.android.osm; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.ProtocolException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import com.orhanobut.mockwebserverplus.MockWebServerPlus; import android.content.Context; import android.content.SharedPreferences; import android.content.res.Resources; import android.preference.PreferenceManager; import android.support.test.InstrumentationRegistry; import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.LargeTest; import de.blau.android.App; import de.blau.android.Logic; import de.blau.android.Main; import de.blau.android.R; import de.blau.android.SignalHandler; import de.blau.android.exception.OsmException; import de.blau.android.exception.OsmServerException; import de.blau.android.prefs.AdvancedPrefDatabase; import de.blau.android.prefs.Preferences; import de.blau.android.resources.TileLayerServer; import de.blau.android.tasks.Note; import de.blau.android.tasks.Task; import de.blau.android.tasks.TransferTasks; import okhttp3.HttpUrl; @RunWith(AndroidJUnit4.class) @LargeTest public class ApiTest { MockWebServerPlus mockServer = null; Context context = null; AdvancedPrefDatabase prefDB = null; Main main = null; @Rule public ActivityTestRule<Main> mActivityRule = new ActivityTestRule<>(Main.class); @Before public void setup() { context = InstrumentationRegistry.getInstrumentation().getTargetContext(); main = mActivityRule.getActivity(); Preferences prefs = new Preferences(context); prefs.setBackGroundLayer(TileLayerServer.LAYER_NONE); // try to avoid downloading tiles main.getMap().setPrefs(main, prefs); mockServer = new MockWebServerPlus(); HttpUrl mockBaseUrl = mockServer.server().url("/api/0.6/"); System.out.println("mock api url " + mockBaseUrl.toString()); prefDB = new AdvancedPrefDatabase(context); prefDB.deleteAPI("Test"); prefDB.addAPI("Test", "Test", mockBaseUrl.toString(), null, null, "user", "pass", null, false); prefDB.selectAPI("Test"); } @After public void teardown() { try { mockServer.server().shutdown(); } catch (IOException ioex) { System.out.println("Stopping mock webserver exception " + ioex); } } @Test public void capabilities() { mockServer.enqueue("capabilities1"); final Server s = new Server(context, prefDB.getCurrentAPI(),"vesupucci test"); Capabilities result = s.getCapabilities(); Assert.assertNotNull(result); Assert.assertEquals(result.minVersion,"0.6"); Assert.assertEquals(result.gpxStatus, Capabilities.Status.ONLINE); Assert.assertEquals(result.apiStatus, Capabilities.Status.ONLINE); Assert.assertEquals(result.dbStatus, Capabilities.Status.ONLINE); Assert.assertEquals(Way.maxWayNodes, 2001); } @Test public void dataDownload() { final CountDownLatch signal = new CountDownLatch(1); mockServer.enqueue("capabilities1"); mockServer.enqueue("download1"); Logic logic = App.getLogic(); try { logic.downloadBox(main, new BoundingBox(8.3879800D,47.3892400D,8.3844600D,47.3911300D), false, new SignalHandler(signal)); } catch (OsmException e) { Assert.fail(e.getMessage()); } try { signal.await(30, TimeUnit.SECONDS); } catch (InterruptedException e) { Assert.fail(e.getMessage()); } Assert.assertNotNull(App.getDelegator().getOsmElement(Node.NAME, 101792984)); } @Test public void dataDownloadMerge() { dataDownload(); final CountDownLatch signal = new CountDownLatch(1); mockServer.enqueue("capabilities1"); mockServer.enqueue("download2"); Logic logic = App.getLogic(); try { logic.downloadBox(main, new BoundingBox(8.3865200D,47.3883000D,8.3838500D,47.3898500D), true, new SignalHandler(signal)); } catch (OsmException e) { Assert.fail(e.getMessage()); } try { signal.await(30, TimeUnit.SECONDS); } catch (InterruptedException e) { Assert.fail(e.getMessage()); } Assert.assertNotNull(App.getDelegator().getOsmElement(Node.NAME, 101792984)); } @Test public void dataUpload() { final CountDownLatch signal = new CountDownLatch(1); Logic logic = App.getLogic(); ClassLoader loader = Thread.currentThread().getContextClassLoader(); InputStream is = loader.getResourceAsStream("test1.osm"); logic.readOsmFile(main, is, false, new SignalHandler(signal)); try { signal.await(30, TimeUnit.SECONDS); } catch (InterruptedException e) { Assert.fail(e.getMessage()); } Assert.assertEquals(App.getDelegator().getApiElementCount(),32); Node n = (Node) App.getDelegator().getOsmElement(Node.NAME, 101792984); Assert.assertNotNull(n); Assert.assertEquals(n.getState(), OsmElement.STATE_MODIFIED); mockServer.enqueue("capabilities1"); mockServer.enqueue("changeset1"); mockServer.enqueue("upload1"); mockServer.enqueue("close_changeset"); final Server s = new Server(context, prefDB.getCurrentAPI(),"vesupucci test"); try { App.getDelegator().uploadToServer(s, "TEST", "none", true); } catch (OsmServerException e) { Assert.fail(e.getMessage()); } catch (MalformedURLException e) { Assert.fail(e.getMessage()); } catch (ProtocolException e) { Assert.fail(e.getMessage()); } catch (IOException e) { Assert.fail(e.getMessage()); } Assert.assertEquals(50000,s.getCachedCapabilities().maxElementsInChangeset); n = (Node) App.getDelegator().getOsmElement(Node.NAME, 101792984); Assert.assertNotNull(n); Assert.assertEquals(n.getState(), OsmElement.STATE_UNCHANGED); Assert.assertEquals(n.getOsmVersion(), 7); Relation r = (Relation) App.getDelegator().getOsmElement(Relation.NAME,2807173); Assert.assertEquals(r.getState(), OsmElement.STATE_UNCHANGED); Assert.assertEquals(r.getOsmVersion(), 4); } @Test public void dataUploadSplit() { final CountDownLatch signal = new CountDownLatch(1); Logic logic = App.getLogic(); ClassLoader loader = Thread.currentThread().getContextClassLoader(); InputStream is = loader.getResourceAsStream("test1.osm"); logic.readOsmFile(main, is, false, new SignalHandler(signal)); try { signal.await(30, TimeUnit.SECONDS); } catch (InterruptedException e) { Assert.fail(e.getMessage()); } Assert.assertEquals(App.getDelegator().getApiElementCount(),32); Node n = (Node) App.getDelegator().getOsmElement(Node.NAME, 101792984); Assert.assertNotNull(n); Assert.assertEquals(n.getState(), OsmElement.STATE_MODIFIED); mockServer.enqueue("capabilities2"); mockServer.enqueue("changeset2"); mockServer.enqueue("upload2"); mockServer.enqueue("close_changeset"); mockServer.enqueue("changeset3"); mockServer.enqueue("upload3"); mockServer.enqueue("close_changeset"); mockServer.enqueue("changeset4"); mockServer.enqueue("upload4"); mockServer.enqueue("close_changeset"); final Server s = new Server(context, prefDB.getCurrentAPI(),"vesupucci test"); try { App.getDelegator().uploadToServer(s, "TEST", "none", false); } catch (OsmServerException e) { Assert.fail(e.getMessage()); } catch (MalformedURLException e) { Assert.fail(e.getMessage()); } catch (ProtocolException e) { Assert.fail(e.getMessage()); } catch (IOException e) { Assert.fail(e.getMessage()); } Assert.assertEquals(11,s.getCachedCapabilities().maxElementsInChangeset); n = (Node) App.getDelegator().getOsmElement(Node.NAME, 101792984); Assert.assertNotNull(n); Assert.assertEquals(n.getState(), OsmElement.STATE_UNCHANGED); Assert.assertEquals(n.getOsmVersion(), 7); Relation r = (Relation) App.getDelegator().getOsmElement(Relation.NAME,2807173); Assert.assertEquals(r.getState(), OsmElement.STATE_UNCHANGED); Assert.assertEquals(r.getOsmVersion(), 4); } @Test public void dataUploadErrors() { final CountDownLatch signal = new CountDownLatch(1); Logic logic = App.getLogic(); // we need something changes in memory or else we wont try to upload ClassLoader loader = Thread.currentThread().getContextClassLoader(); InputStream is = loader.getResourceAsStream("test1.osm"); logic.readOsmFile(main, is, false, new SignalHandler(signal)); try { signal.await(30, TimeUnit.SECONDS); } catch (InterruptedException e) { Assert.fail(e.getMessage()); } Assert.assertTrue(App.getDelegator().getApiElementCount() > 0); uploadErrorTest(401); uploadErrorTest(403); uploadErrorTest(999); } private void uploadErrorTest(int code) { mockServer.enqueue("capabilities1"); mockServer.enqueue("" + code); final Server s = new Server(context, prefDB.getCurrentAPI(),"vesupucci test"); s.resetChangeset(); try { App.getDelegator().uploadToServer(s, "TEST", "none", true); } catch (OsmServerException e) { System.out.println(e.getMessage()); Assert.assertEquals(code,e.getErrorCode()); return; } catch (MalformedURLException e) { Assert.fail(e.getMessage()); return; } catch (ProtocolException e) { Assert.fail(e.getMessage()); return; } catch (IOException e) { Assert.fail(e.getMessage()); return; } Assert.fail("Expected error " + code); } @Test public void dataDownloadErrors() { downloadErrorTest(400); downloadErrorTest(401); downloadErrorTest(403); downloadErrorTest(999); } private void downloadErrorTest(int code) { final CountDownLatch signal = new CountDownLatch(1); mockServer.enqueue("capabilities1"); mockServer.enqueue("" + code); Logic logic = App.getLogic(); try { logic.downloadBox(main, new BoundingBox(8.3879800D,47.3892400D,8.3844600D,47.3911300D), false, new SignalHandler(signal)); } catch (OsmException e) { Assert.fail(e.getMessage()); } try { signal.await(30, TimeUnit.SECONDS); } catch (InterruptedException e) { Assert.fail(e.getMessage()); } } @Test public void notesDownload() { final CountDownLatch signal = new CountDownLatch(1); // mockServer.enqueue("capabilities1"); mockServer.enqueue("notesDownload1"); App.getTaskStorage().reset(); try { final Server s = new Server(context, prefDB.getCurrentAPI(),"vesupucci test"); SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(context); Resources r = context.getResources(); String notesSelector = r.getString(R.string.bugfilter_notes); Set<String> set = new HashSet<String>(Arrays.asList(notesSelector)) ; p.edit().putStringSet(r.getString(R.string.config_bugFilter_key), set).commit(); Assert.assertTrue(new Preferences(context).taskFilter().contains(notesSelector)); TransferTasks.downloadBox(context,s,new BoundingBox(8.3879800D,47.3892400D,8.3844600D,47.3911300D), false, new SignalHandler(signal)); } catch (Exception e) { Assert.fail(e.getMessage()); } try { signal.await(40, TimeUnit.SECONDS); } catch (InterruptedException e) { Assert.fail(e.getMessage()); } ArrayList<Task> tasks = App.getTaskStorage().getTasks(); // note the fixture contains 100 notes, however 41 of them are closed and expired Assert.assertEquals(59, tasks.size()); try { tasks = App.getTaskStorage().getTasks(new BoundingBox(-0.0917, 51.532, -0.0918, 51.533)); } catch (Exception e){ Assert.fail(e.getMessage()); } Assert.assertTrue(tasks.get(0) instanceof Note); Assert.assertEquals(458427,tasks.get(0).getId()); } @Test public void noteUpload() { final CountDownLatch signal = new CountDownLatch(1); mockServer.enqueue("noteUpload1"); App.getTaskStorage().reset(); try { final Server s = new Server(context, prefDB.getCurrentAPI(),"vesupucci test"); Note n = new Note((int)(51.0*1E7D),(int)(0.1*1E7D)); Assert.assertTrue(n.isNew()); Assert.assertTrue(TransferTasks.uploadNote(main, s, n, "ThisIsANote", false, false, new SignalHandler(signal))); } catch (Exception e) { Assert.fail(e.getMessage()); } try { signal.await(40, TimeUnit.SECONDS); } catch (InterruptedException e) { Assert.fail(e.getMessage()); } try { ArrayList<Task>tasks = App.getTaskStorage().getTasks(new BoundingBox(0.099, 50.99, 0.111, 51.01)); Assert.assertEquals(1, tasks.size()); Note n = (Note) tasks.get(0); Assert.assertEquals("<p>ThisIsANote</p>",n.getLastComment().getText()); } catch (Exception e) { Assert.fail(e.getMessage()); } } }