From 6b7eb796f0929e1dd14e0f66ee3f31fa50489b28 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Tue, 20 Sep 2016 10:21:16 +0900 Subject: [PATCH] Fixed unit tests, use Robolectric for some tests --- build.gradle | 2 + .../syncthingandroid/test/MockRestApi.java | 3 +- .../test/MockSyncthingService.java | 2 +- .../test/syncthing/RestApiTest.java | 2 - .../test/syncthing/SyncthingServiceTest.java | 121 ------------------ .../test/util/ConfigXmlTest.java | 13 -- .../syncthingandroid/util/ConfigXml.java | 14 +- .../syncthing/SyncthingServiceTest.java | 106 +++++++++++++++ 8 files changed, 111 insertions(+), 152 deletions(-) delete mode 100644 src/androidTest/java/com/nutomic/syncthingandroid/test/syncthing/SyncthingServiceTest.java create mode 100644 src/test/java/com/nutomic/syncthingandroid/syncthing/SyncthingServiceTest.java diff --git a/build.gradle b/build.gradle index e9f66baa..542280a0 100644 --- a/build.gradle +++ b/build.gradle @@ -26,6 +26,8 @@ dependencies { compile 'com.google.zxing:android-integration:3.2.1' compile 'com.google.code.gson:gson:2.7' compile 'org.mindrot:jbcrypt:0.3m' + testCompile 'junit:junit:4.12' + testCompile 'org.robolectric:robolectric:3.1.2' androidTestCompile 'com.squareup.okhttp:mockwebserver:2.4.0' } diff --git a/src/androidTest/java/com/nutomic/syncthingandroid/test/MockRestApi.java b/src/androidTest/java/com/nutomic/syncthingandroid/test/MockRestApi.java index d6d04710..d21d5227 100644 --- a/src/androidTest/java/com/nutomic/syncthingandroid/test/MockRestApi.java +++ b/src/androidTest/java/com/nutomic/syncthingandroid/test/MockRestApi.java @@ -11,9 +11,8 @@ import java.util.List; public class MockRestApi extends RestApi { public MockRestApi(Context context, String url, String apiKey, - String guiUser, String guiPassword, OnApiAvailableListener listener) { - super(context, url, apiKey, guiUser, guiPassword, listener, null); + super(context, url, apiKey, listener, null); } @Override diff --git a/src/androidTest/java/com/nutomic/syncthingandroid/test/MockSyncthingService.java b/src/androidTest/java/com/nutomic/syncthingandroid/test/MockSyncthingService.java index 48140553..da4fa1cc 100644 --- a/src/androidTest/java/com/nutomic/syncthingandroid/test/MockSyncthingService.java +++ b/src/androidTest/java/com/nutomic/syncthingandroid/test/MockSyncthingService.java @@ -49,7 +49,7 @@ public class MockSyncthingService extends SyncthingService { @Override public RestApi getApi() { - return new MockRestApi(this, null, null, null, null, null); + return new MockRestApi(this, null, null, null); } @Override diff --git a/src/androidTest/java/com/nutomic/syncthingandroid/test/syncthing/RestApiTest.java b/src/androidTest/java/com/nutomic/syncthingandroid/test/syncthing/RestApiTest.java index c67d359c..b9d95066 100644 --- a/src/androidTest/java/com/nutomic/syncthingandroid/test/syncthing/RestApiTest.java +++ b/src/androidTest/java/com/nutomic/syncthingandroid/test/syncthing/RestApiTest.java @@ -26,7 +26,6 @@ public class RestApiTest extends AndroidTestCase { new SyncthingRunnable(new MockContext(getContext()), SyncthingRunnable.Command.main); ConfigXml config = new ConfigXml(new MockContext(getContext())); - config.changeDefaultFolder(); String httpsCertPath = getContext().getFilesDir() + "/" + SyncthingService.HTTPS_CERT_FILE; @@ -39,7 +38,6 @@ public class RestApiTest extends AndroidTestCase { } }.execute(config.getWebGuiUrl()); mApi = new RestApi(getContext(), config.getWebGuiUrl(), config.getApiKey(), - null, null, new RestApi.OnApiAvailableListener() { @Override public void onApiAvailable() { diff --git a/src/androidTest/java/com/nutomic/syncthingandroid/test/syncthing/SyncthingServiceTest.java b/src/androidTest/java/com/nutomic/syncthingandroid/test/syncthing/SyncthingServiceTest.java deleted file mode 100644 index 33d6c963..00000000 --- a/src/androidTest/java/com/nutomic/syncthingandroid/test/syncthing/SyncthingServiceTest.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.nutomic.syncthingandroid.test.syncthing; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Handler; -import android.preference.PreferenceManager; -import android.test.ServiceTestCase; - -import com.nutomic.syncthingandroid.syncthing.SyncthingService; -import com.nutomic.syncthingandroid.syncthing.SyncthingServiceBinder; -import com.nutomic.syncthingandroid.test.MockContext; -import com.nutomic.syncthingandroid.test.Util; -import com.nutomic.syncthingandroid.util.ConfigXml; - -import java.io.File; -import java.io.IOException; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * These tests assume that syncthing keys have already been generated. If not, tests may fail - * because startup takes too long. - */ -public class SyncthingServiceTest extends ServiceTestCase { - - private Context mContext; - - public SyncthingServiceTest() { - super(SyncthingService.class); - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - mContext = new MockContext(getContext()); - } - - @Override - protected void tearDown() throws Exception { - Util.deleteRecursive(mContext.getFilesDir()); - PreferenceManager.getDefaultSharedPreferences(getContext()).edit().clear().commit(); - super.tearDown(); - } - - public void testFirstStart() { - setContext(mContext); - startService(new Intent(mContext, SyncthingService.class)); - assertTrue(getService().isFirstStart()); - } - - public void testNotFirstStart() throws IOException { - setContext(mContext); - startService(new Intent(mContext, SyncthingService.class)); - new File(mContext.getFilesDir(), SyncthingService.PUBLIC_KEY_FILE).createNewFile(); - assertFalse(getService().isFirstStart()); - } - - public void testBindService() throws InterruptedException { - SyncthingServiceBinder binder = (SyncthingServiceBinder) - bindService(new Intent(getContext(), SyncthingService.class)); - SyncthingService service = binder.getService(); - final CountDownLatch latch = new CountDownLatch(2); - getService().registerOnWebGuiAvailableListener(new SyncthingService.OnWebGuiAvailableListener() { - @Override - public void onWebGuiAvailable() { - latch.countDown(); - } - }); - getService().registerOnApiChangeListener(new SyncthingService.OnApiChangeListener() { - @Override - public void onApiChange(SyncthingService.State currentState) { - latch.countDown(); - } - }); - latch.await(1, TimeUnit.SECONDS); - assertNotNull(service); - } - - public void testImportExportConfig() { - setContext(mContext); - SyncthingServiceBinder binder = (SyncthingServiceBinder) - bindService(new Intent(getContext(), SyncthingService.class)); - SyncthingService service = binder.getService(); - File config = new File(mContext.getFilesDir(), ConfigXml.CONFIG_FILE); - File privateKey = new File(mContext.getFilesDir(), SyncthingService.PRIVATE_KEY_FILE); - File publicKey = new File(mContext.getFilesDir(), SyncthingService.PUBLIC_KEY_FILE); - - try { - config.createNewFile(); - privateKey.createNewFile(); - publicKey.createNewFile(); - } catch (IOException e) { - fail(); - } - - service.exportConfig(); - - config.delete(); - privateKey.delete(); - publicKey.delete(); - - service.importConfig(); - assertTrue(config.exists()); - assertTrue(privateKey.exists()); - assertTrue(publicKey.exists()); - } - - public void testPassword() throws InterruptedException { - startService(new Intent(getContext(), SyncthingService.class)); - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - assertNotNull(sp.getString("gui_user", null)); - assertEquals(20, sp.getString("gui_password", null).length()); - } - }, 5000); - } - -} diff --git a/src/androidTest/java/com/nutomic/syncthingandroid/test/util/ConfigXmlTest.java b/src/androidTest/java/com/nutomic/syncthingandroid/test/util/ConfigXmlTest.java index 21eb6491..0bbb6ab2 100644 --- a/src/androidTest/java/com/nutomic/syncthingandroid/test/util/ConfigXmlTest.java +++ b/src/androidTest/java/com/nutomic/syncthingandroid/test/util/ConfigXmlTest.java @@ -38,17 +38,4 @@ public class ConfigXmlTest extends AndroidTestCase { assertTrue(mConfig.getWebGuiUrl().startsWith("https://127.0.0.1:")); } - /** - * Just make sure the file is actually changed. - * - * This is not ideal, but way less complicated than starting up syncthing and accessing the API. - */ - public void testCreateCameraFolder() { - long oldTime = ConfigXml.getConfigFile(mContext).lastModified(); - long oldSize = ConfigXml.getConfigFile(mContext).length(); - mConfig.changeDefaultFolder(); - assertNotSame(oldTime, ConfigXml.getConfigFile(mContext).lastModified()); - assertNotSame(oldSize, ConfigXml.getConfigFile(mContext).lastModified()); - } - } diff --git a/src/main/java/com/nutomic/syncthingandroid/util/ConfigXml.java b/src/main/java/com/nutomic/syncthingandroid/util/ConfigXml.java index 963a29b7..4ef90dce 100644 --- a/src/main/java/com/nutomic/syncthingandroid/util/ConfigXml.java +++ b/src/main/java/com/nutomic/syncthingandroid/util/ConfigXml.java @@ -59,8 +59,6 @@ public class ConfigXml { */ public static final String CONFIG_FILE = "config.xml"; - private static final String INVALID_CONFIG_FILE = "config.xml.invalid"; - private static final int OPEN_CONFIG_MAX_TRIES = 10; private final Context mContext; @@ -83,19 +81,9 @@ public class ConfigXml { DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); mConfig = db.parse(mConfigFile); } catch (SAXException | ParserConfigurationException | IOException e) { - Log.w(TAG, "Failed to open config, moving to " + INVALID_CONFIG_FILE + - " and creating blank config"); - File dest = new File(mConfigFile.getParent(), INVALID_CONFIG_FILE); - if (dest.exists()) - dest.delete(); - mConfigFile.renameTo(dest); - generateKeysConfig(context); - isFirstStart = true; - mConfigFile = getConfigFile(context); + throw new OpenConfigException(); } } - if (mConfig == null) - throw new OpenConfigException(); if (isFirstStart) { changeDefaultFolder(); diff --git a/src/test/java/com/nutomic/syncthingandroid/syncthing/SyncthingServiceTest.java b/src/test/java/com/nutomic/syncthingandroid/syncthing/SyncthingServiceTest.java new file mode 100644 index 00000000..42d7cf2c --- /dev/null +++ b/src/test/java/com/nutomic/syncthingandroid/syncthing/SyncthingServiceTest.java @@ -0,0 +1,106 @@ +package com.nutomic.syncthingandroid.syncthing; + +import android.content.SharedPreferences; +import android.os.Handler; +import android.preference.PreferenceManager; +import com.nutomic.syncthingandroid.BuildConfig; +import com.nutomic.syncthingandroid.util.ConfigXml; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.*; + +/** + * These tests assume that syncthing keys have already been generated. If not, tests may fail + * because startup takes too long. + */ +@RunWith(RobolectricTestRunner.class) +@Config(constants = BuildConfig.class) +public class SyncthingServiceTest { + + private SyncthingService mService; + + @Before + public void setup() { + mService = Robolectric.buildService(SyncthingService.class).get(); + mService.onCreate(); + } + + @Test + public void testFirstStart() { + assertTrue(mService.isFirstStart()); + } + + @Test + public void testNotFirstStart() throws IOException { + new File(mService.getFilesDir(), SyncthingService.PUBLIC_KEY_FILE).createNewFile(); + assertFalse(mService.isFirstStart()); + } + + @Test + public void testBindService() throws InterruptedException { + final CountDownLatch latch = new CountDownLatch(2); + mService.registerOnWebGuiAvailableListener(new SyncthingService.OnWebGuiAvailableListener() { + @Override + public void onWebGuiAvailable() { + latch.countDown(); + } + }); + mService.registerOnApiChangeListener(new SyncthingService.OnApiChangeListener() { + @Override + public void onApiChange(SyncthingService.State currentState) { + latch.countDown(); + } + }); + latch.await(1, TimeUnit.SECONDS); + assertNotNull(mService); + } + + @Test + public void testImportExportConfig() { + File config = new File(mService.getFilesDir(), ConfigXml.CONFIG_FILE); + File privateKey = new File(mService.getFilesDir(), SyncthingService.PRIVATE_KEY_FILE); + File publicKey = new File(mService.getFilesDir(), SyncthingService.PUBLIC_KEY_FILE); + + try { + config.createNewFile(); + privateKey.createNewFile(); + publicKey.createNewFile(); + } catch (IOException e) { + fail(); + } + + mService.exportConfig(); + + config.delete(); + privateKey.delete(); + publicKey.delete(); + + assertTrue(mService.importConfig()); + assertTrue(config.exists()); + assertTrue(privateKey.exists()); + assertTrue(publicKey.exists()); + } + + @Test + public void testPassword() throws InterruptedException { + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mService); + assertNotNull(sp.getString("gui_user", null)); + assertEquals(20, sp.getString("gui_password", null).length()); + } + }, 5000); + } + +}