summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/build.gradle14
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java3
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/BitmaskApp.java26
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java34
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/Dashboard.java3
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/MainActivity.java34
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java3
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/StartActivity.java34
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java81
-rw-r--r--app/src/main/res/values/strings.xml2
-rw-r--r--app/src/test/java/se/leap/bitmaskclient/ConfigHelperTest.java57
11 files changed, 234 insertions, 57 deletions
diff --git a/app/build.gradle b/app/build.gradle
index cb865ecd..b28d9f35 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -77,6 +77,9 @@ dependencies {
androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.6.3'
testCompile 'junit:junit:4.12'
testCompile 'org.json:json:20170516'
+ debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.4'
+ releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'
+ betaCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'
compile 'com.jakewharton:butterknife:6.1.0'
provided 'com.squareup.dagger:dagger-compiler:1.2.2'
compile 'com.github.pedrovgs:renderers:1.5'
@@ -92,6 +95,17 @@ dependencies {
compile 'com.android.support:support-fragment:26.1.0'
}
+// Ensure the no-op dependency is always used in JVM tests.
+configurations.all { config ->
+ if (config.name.contains('UnitTest')) {
+ config.resolutionStrategy.eachDependency { details ->
+ if (details.requested.group == 'com.squareup.leakcanary' && details.requested.name == 'leakcanary-android') {
+ details.useTarget(group: details.requested.group, name: 'leakcanary-android-no-op', version: details.requested.version)
+ }
+ }
+ }
+}
+
def processFileInplace(file, Closure processText) {
def text = file.text
file.write(processText(text))
diff --git a/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java b/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java
index cb5f334b..a596cc7f 100644
--- a/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/AbstractProviderDetailActivity.java
@@ -21,6 +21,8 @@ import butterknife.InjectView;
import static se.leap.bitmaskclient.Constants.PROVIDER_ALLOW_ANONYMOUS;
import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
+import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES;
+import static se.leap.bitmaskclient.MainActivity.ACTION_SHOW_VPN_FRAGMENT;
public abstract class AbstractProviderDetailActivity extends ConfigWizardBaseActivity {
@@ -72,6 +74,7 @@ public abstract class AbstractProviderDetailActivity extends ConfigWizardBaseAct
} else {
Log.d(TAG, "use anonymously selected");
intent = new Intent(getApplicationContext(), MainActivity.class);
+ intent.setAction(ACTION_SHOW_VPN_FRAGMENT);
}
intent.putExtra(PROVIDER_KEY, provider);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
diff --git a/app/src/main/java/se/leap/bitmaskclient/BitmaskApp.java b/app/src/main/java/se/leap/bitmaskclient/BitmaskApp.java
index 88a01b62..f9e45b79 100644
--- a/app/src/main/java/se/leap/bitmaskclient/BitmaskApp.java
+++ b/app/src/main/java/se/leap/bitmaskclient/BitmaskApp.java
@@ -1,6 +1,10 @@
package se.leap.bitmaskclient;
import android.app.Application;
+import android.content.Context;
+
+import com.squareup.leakcanary.LeakCanary;
+import com.squareup.leakcanary.RefWatcher;
/**
* Created by cyberta on 24.10.17.
@@ -8,11 +12,31 @@ import android.app.Application;
public class BitmaskApp extends Application {
+ private RefWatcher refWatcher;
+
@Override
public void onCreate() {
super.onCreate();
+ if (LeakCanary.isInAnalyzerProcess(this)) {
+ // This process is dedicated to LeakCanary for heap analysis.
+ // You should not init your app in this process.
+ return;
+ }
+ refWatcher = LeakCanary.install(this);
+ // Normal app init code...*/
PRNGFixes.apply();
- //TODO: add LeakCanary!
}
+ /**
+ * Use this method to get a RefWatcher object that checks for memory leaks in the given context.
+ * Call refWatcher.watch(this) to check if all references get garbage collected.
+ * @param context
+ * @return the RefWatcher object
+ */
+ public static RefWatcher getRefWatcher(Context context) {
+ BitmaskApp application = (BitmaskApp) context.getApplicationContext();
+ return application.refWatcher;
+ }
+
+
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java
index 0e861059..ccdf5064 100644
--- a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java
+++ b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java
@@ -16,6 +16,7 @@
*/
package se.leap.bitmaskclient;
+import android.content.SharedPreferences;
import android.support.annotation.NonNull;
import android.util.Log;
@@ -28,8 +29,9 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.KeyStoreException;
@@ -45,6 +47,7 @@ import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import static android.R.attr.name;
+import static se.leap.bitmaskclient.Constants.PROVIDER_CONFIGURED;
/**
* Stores constants, and implements auxiliary methods used across all Bitmask Android classes.
@@ -256,4 +259,33 @@ public class ConfigHelper {
public static KeyStore getKeystore() {
return keystore_trusted;
}
+
+
+ public static String getCurrentProviderName(@NonNull SharedPreferences preferences) {
+ try {
+ JSONObject providerDefintion = new JSONObject(preferences.getString(Provider.KEY, ""));
+ return providerDefintion.getString(Provider.DOMAIN);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static boolean providerInSharedPreferences(@NonNull SharedPreferences preferences) {
+ return preferences.getBoolean(PROVIDER_CONFIGURED, false);
+ }
+
+ public static Provider getSavedProviderFromSharedPreferences(@NonNull SharedPreferences preferences) {
+ Provider provider = new Provider();
+ try {
+ provider.setUrl(new URL(preferences.getString(Provider.MAIN_URL, "")));
+ provider.define(new JSONObject(preferences.getString(Provider.KEY, "")));
+ provider.setCACert(preferences.getString(Provider.CA_CERT, ""));
+ } catch (MalformedURLException | JSONException e) {
+ e.printStackTrace();
+ }
+
+ return provider;
+ }
+
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java
index 82ff9db8..5ccb48b5 100644
--- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java
+++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java
@@ -18,7 +18,6 @@ package se.leap.bitmaskclient;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
-import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -42,8 +41,8 @@ import java.util.List;
import java.util.Map;
import butterknife.InjectView;
-import se.leap.bitmaskclient.fragments.AboutFragment;
import de.blinkt.openvpn.core.VpnStatus;
+import se.leap.bitmaskclient.fragments.AboutFragment;
import se.leap.bitmaskclient.userstatus.SessionDialog;
import se.leap.bitmaskclient.userstatus.User;
import se.leap.bitmaskclient.userstatus.UserStatusFragment;
diff --git a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
index 41e496bb..40a9052c 100644
--- a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
@@ -1,7 +1,9 @@
package se.leap.bitmaskclient;
+import android.content.Intent;
import android.os.Bundle;
+import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
@@ -16,6 +18,7 @@ public class MainActivity extends AppCompatActivity {
private static Provider provider = new Provider();
private static FragmentManagerEnhanced fragmentManager;
+ public final static String ACTION_SHOW_VPN_FRAGMENT = "action_show_vpn_fragment";
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
@@ -37,6 +40,7 @@ public class MainActivity extends AppCompatActivity {
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
+ handleIntentAction(getIntent());
}
public static void sessionDialog(Bundle resultData) {
@@ -48,4 +52,34 @@ public class MainActivity extends AppCompatActivity {
}
}
+ @Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ setIntent(intent);
+ handleIntentAction(intent);
+ }
+
+ private void handleIntentAction(Intent intent) {
+ if (intent == null || intent.getAction() == null) {
+ return;
+ }
+
+ Fragment fragment = null;
+
+ switch (intent.getAction()) {
+ case ACTION_SHOW_VPN_FRAGMENT:
+ fragment = new VpnFragment();
+ break;
+ default:
+ break;
+ }
+
+ if (fragment != null) {
+ fragmentManager.beginTransaction()
+ .replace(R.id.container, fragment)
+ .commit();
+ }
+ }
+
+
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java
index 1d1908a6..67f4e787 100644
--- a/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/ProviderCredentialsBaseActivity.java
@@ -23,6 +23,8 @@ import se.leap.bitmaskclient.userstatus.SessionDialog;
import se.leap.bitmaskclient.userstatus.SessionDialog.ERRORS;
import se.leap.bitmaskclient.userstatus.User;
+import static se.leap.bitmaskclient.MainActivity.ACTION_SHOW_VPN_FRAGMENT;
+
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
@@ -359,6 +361,7 @@ public abstract class ProviderCredentialsBaseActivity extends ConfigWizardBaseAc
case ProviderAPI.CORRECTLY_DOWNLOADED_CERTIFICATE:
intent = new Intent(ProviderCredentialsBaseActivity.this, MainActivity.class);
+ intent.setAction(ACTION_SHOW_VPN_FRAGMENT);
startActivity(intent);
//activity.eip_fragment.updateEipService();
break;
diff --git a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
index 43d7f152..bb01ddc0 100644
--- a/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/StartActivity.java
@@ -15,7 +15,9 @@ import java.lang.annotation.RetentionPolicy;
import de.blinkt.openvpn.core.VpnStatus;
import se.leap.bitmaskclient.userstatus.User;
+import static se.leap.bitmaskclient.Constants.APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE;
import static se.leap.bitmaskclient.Constants.PREFERENCES_APP_VERSION;
+import static se.leap.bitmaskclient.Constants.REQUEST_CODE_CONFIGURE_LEAP;
import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES;
/**
@@ -71,9 +73,8 @@ public class StartActivity extends Activity {
VpnStatus.initLogCache(getApplicationContext().getCacheDir());
User.init(getString(R.string.default_username));
- // go to Dashboard
- Intent intent = new Intent(this, MainActivity.class);
- startActivity(intent);
+ prepareEIP();
+
}
/**
@@ -141,4 +142,31 @@ public class StartActivity extends Activity {
preferences.edit().putInt(PREFERENCES_APP_VERSION, versionCode).apply();
}
+ private void prepareEIP() {
+ boolean provider_exists = ConfigHelper.providerInSharedPreferences(preferences);
+ if (provider_exists) {
+ Provider provider = ConfigHelper.getSavedProviderFromSharedPreferences(preferences);
+ if(!provider.isConfigured()) {
+ configureLeapProvider();
+ } else {
+ Log.d(TAG, "vpn provider is configured");
+
+ //buildDashboard(getIntent().getBooleanExtra(EIP_RESTART_ON_BOOT, false));
+// user_status_fragment.restoreSessionStatus(savedInstanceState);
+ Intent intent = new Intent(this, MainActivity.class);
+ intent.setAction(MainActivity.ACTION_SHOW_VPN_FRAGMENT);
+ startActivity(intent);
+ }
+ } else {
+ configureLeapProvider();
+ }
+ }
+
+ private void configureLeapProvider() {
+ if (getIntent().hasExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE)) {
+ getIntent().removeExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE);
+ }
+ startActivityForResult(new Intent(this, ConfigurationWizard.class), REQUEST_CODE_CONFIGURE_LEAP);
+ }
+
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java
index 566134dd..dbe99dce 100644
--- a/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/drawer/NavigationDrawerFragment.java
@@ -6,7 +6,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
-import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.GravityCompat;
@@ -27,15 +26,15 @@ import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
+import se.leap.bitmaskclient.ConfigHelper;
import se.leap.bitmaskclient.ConfigurationWizard;
-import se.leap.bitmaskclient.Provider;
import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.VpnFragment;
import se.leap.bitmaskclient.fragments.AboutFragment;
import se.leap.bitmaskclient.fragments.LogFragment;
-import se.leap.bitmaskclient.userstatus.User;
-import se.leap.bitmaskclient.userstatus.UserStatusFragment;
+import static android.content.Context.MODE_PRIVATE;
+import static se.leap.bitmaskclient.BitmaskApp.getRefWatcher;
import static se.leap.bitmaskclient.Constants.REQUEST_CODE_SWITCH_PROVIDER;
import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES;
@@ -47,11 +46,6 @@ import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES;
public class NavigationDrawerFragment extends Fragment {
/**
- * Remember the position of the selected item.
- */
- private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
-
- /**
* Per the design guidelines, you should show the drawer on launch until the user manually
* expands it. This shared preference tracks this.
*/
@@ -67,8 +61,8 @@ public class NavigationDrawerFragment extends Fragment {
private ListView mDrawerSettingsListView;
private ListView mDrawerAccountsListView;
private View mFragmentContainerView;
+ private ArrayAdapter<String> accountListAdapter;
- private int mCurrentSelectedPosition = 0;
private boolean mFromSavedInstanceState;
private boolean mUserLearnedDrawer;
@@ -85,20 +79,8 @@ public class NavigationDrawerFragment extends Fragment {
// Read in the flag indicating whether or not the user has demonstrated awareness of the
// drawer. See PREF_USER_LEARNED_DRAWER for details.
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
- mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
-
- preferences = getActivity().getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE);
-
- if (savedInstanceState != null) {
- mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
- mFromSavedInstanceState = true;
- }
-
- // Select either the default item (0) or the last selected item.
- if (mDrawerSettingsListView != null) {
- selectItem(mDrawerSettingsListView, mCurrentSelectedPosition);
- }
+ preferences = getContext().getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ mUserLearnedDrawer = preferences.getBoolean(PREF_USER_LEARNED_DRAWER, false);
}
@Override
@@ -142,12 +124,10 @@ public class NavigationDrawerFragment extends Fragment {
android.R.layout.simple_list_item_activated_1,
android.R.id.text1,
new String[]{
- getString(R.string.vpn_fragment_title),
getString(R.string.switch_provider_menu_option),
getString(R.string.log_fragment_title),
getString(R.string.about_fragment_title),
}));
- mDrawerSettingsListView.setItemChecked(mCurrentSelectedPosition, true);
mDrawerAccountsListView = mDrawerView.findViewById(R.id.accountList);
mDrawerAccountsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@@ -157,14 +137,21 @@ public class NavigationDrawerFragment extends Fragment {
}
});
- mDrawerAccountsListView.setAdapter(new ArrayAdapter<String>(
- actionBar.getThemedContext(),
+
+
+ accountListAdapter = new ArrayAdapter<>(actionBar.getThemedContext(),
android.R.layout.simple_list_item_activated_1,
- android.R.id.text1,
- new String[]{
- User.userName(),
- }));
- mDrawerAccountsListView.setItemChecked(mCurrentSelectedPosition, true);
+ android.R.id.text1);
+
+ String providerName = ConfigHelper.getCurrentProviderName(preferences);
+ if (providerName == null) {
+ //TODO: ADD A header to the ListView containing a useful message.
+ //TODO 2: disable switchProvider
+ } else {
+ accountListAdapter.add(providerName);
+ }
+
+ mDrawerAccountsListView.setAdapter(accountListAdapter);
mFragmentContainerView = activity.findViewById(fragmentId);
mDrawerLayout = drawerLayout;
@@ -204,9 +191,7 @@ public class NavigationDrawerFragment extends Fragment {
// The user manually opened the drawer; store this flag to prevent auto-showing
// the navigation drawer automatically in the future.
mUserLearnedDrawer = true;
- SharedPreferences sp = PreferenceManager
- .getDefaultSharedPreferences(getActivity());
- sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
+ preferences.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
}
getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
@@ -228,11 +213,9 @@ public class NavigationDrawerFragment extends Fragment {
});
mDrawerLayout.addDrawerListener(mDrawerToggle);
- selectItem(mDrawerSettingsListView, 0);
}
private void selectItem(AdapterView<?> list, int position) {
- mCurrentSelectedPosition = position;
if (list != null) {
((ListView) list).setItemChecked(position, true);
}
@@ -255,7 +238,6 @@ public class NavigationDrawerFragment extends Fragment {
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
}
@Override
@@ -287,6 +269,12 @@ public class NavigationDrawerFragment extends Fragment {
return super.onOptionsItemSelected(item);
}
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ getRefWatcher(getActivity()).watch(this);
+ }
+
/**
* Per the navigation drawer design guidelines, updates the action bar to show the global app
* 'context', rather than just what's in the current screen.
@@ -307,31 +295,26 @@ public class NavigationDrawerFragment extends Fragment {
Fragment fragment = null;
if (parent == mDrawerAccountsListView) {
- mTitle = User.userName();
- fragment = new UserStatusFragment();
- Bundle bundle = new Bundle();
- bundle.putBoolean(Provider.ALLOW_REGISTRATION, new Provider().allowsRegistration());
- fragment.setArguments(bundle);
+ mTitle = getString(R.string.vpn_fragment_title);
+ fragment = new VpnFragment();
} else {
Log.d("Drawer", String.format("Selected position %d", position));
switch (position) {
- case 1:
+ case 0:
// TODO STOP VPN
// if (provider.hasEIP()) eip_fragment.stopEipIfPossible();
preferences.edit().clear().apply();
startActivityForResult(new Intent(getActivity(), ConfigurationWizard.class), REQUEST_CODE_SWITCH_PROVIDER);
break;
- case 2:
+ case 1:
mTitle = getString(R.string.log_fragment_title);
fragment = new LogFragment();
break;
- case 3:
+ case 2:
mTitle = getString(R.string.about_fragment_title);
fragment = new AboutFragment();
break;
default:
- mTitle = getString(R.string.vpn_fragment_title);
- fragment = new VpnFragment();
break;
}
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 3b278091..01715c32 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -67,7 +67,7 @@
<string name="eip_status_start_pending">Initiating connection</string>
<string name="eip_cancel_connect_title">Cancel connection?</string>
<string name="eip_cancel_connect_text">There is a connection attempt in progress. Do you wish to cancel it?</string>
- <string name="eip.warning.browser_inconsistency">In order to avoid leaking your personal information, please close your browser and start a private window after disconnecting the Encrypted VPN Internet Access. Thanks.</string>
+ <string name="eip.warning.browser_inconsistency">Turn off VPN connection? When the VPN is off, you may leak personal information to your Internet provider or local network.</string>
<string name="eip_state_not_connected">"Not running! Insecure connection!"</string>
<string name="eip_state_connected">Connection Secure.</string>
<string name="provider_problem">It seems there is a problem with the provider.</string>
diff --git a/app/src/test/java/se/leap/bitmaskclient/ConfigHelperTest.java b/app/src/test/java/se/leap/bitmaskclient/ConfigHelperTest.java
new file mode 100644
index 00000000..a9a5733d
--- /dev/null
+++ b/app/src/test/java/se/leap/bitmaskclient/ConfigHelperTest.java
@@ -0,0 +1,57 @@
+package se.leap.bitmaskclient;
+
+import android.content.SharedPreferences;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import se.leap.bitmaskclient.testutils.MockSharedPreferences;
+import se.leap.bitmaskclient.testutils.TestSetupHelper;
+
+import static org.junit.Assert.*;
+import static se.leap.bitmaskclient.Constants.PROVIDER_CONFIGURED;
+import static se.leap.bitmaskclient.testutils.TestSetupHelper.getInputAsString;
+
+/**
+ * Created by cyberta on 17.01.18.
+ */
+public class ConfigHelperTest {
+
+ private SharedPreferences mockPreferences;
+
+
+ @Before
+ public void setup() {
+ mockPreferences = new MockSharedPreferences();
+ }
+
+ @Test
+ public void providerInSharedPreferences_notInPreferences_returnsFalse() throws Exception {
+ assertFalse(ConfigHelper.providerInSharedPreferences(mockPreferences));
+ }
+
+ @Test
+ public void providerInSharedPreferences_inPreferences_returnsTrue() throws Exception {
+ mockPreferences.edit().putBoolean(PROVIDER_CONFIGURED, true).apply();
+ assertTrue(ConfigHelper.providerInSharedPreferences(mockPreferences));
+ }
+
+ @Test
+ public void getSavedProviderFromSharedPreferences_notInPreferences_returnsDefaultProvider() throws Exception {
+ Provider provider = ConfigHelper.getSavedProviderFromSharedPreferences(mockPreferences);
+ assertFalse(provider.isConfigured());
+ }
+
+ @Test
+ public void getSavedProviderFromSharedPreferences_notInPreferences_returnsConfiguredProvider() throws Exception {
+ mockPreferences.edit()
+ .putString(Provider.KEY, getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.json")))
+ .putString(Provider.MAIN_URL, "https://riseup.net")
+ .putString(Provider.CA_CERT, getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.pem")))
+ .apply();
+ Provider provider = ConfigHelper.getSavedProviderFromSharedPreferences(mockPreferences);
+ assertTrue(provider.isConfigured());
+ }
+
+
+} \ No newline at end of file