summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcyBerta <cyberta@riseup.net>2021-12-18 01:40:16 +0100
committercyBerta <cyberta@riseup.net>2021-12-21 00:13:33 +0100
commit7adf788272e8d24951d0005acaf74d598ba7ed22 (patch)
tree2a1a59eb054a62d54a3ab345637d5289d9015437
parentf6cc3e6ad236c3923b398b2ceae9bf2b472dc43a (diff)
improve error handling message for custom branded clients in case of misconfigured backend
-rw-r--r--app/src/main/res/values/strings.xml1
-rw-r--r--app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java6
-rw-r--r--app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java67
-rw-r--r--app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java11
-rw-r--r--app/src/test/resources/error_messages.json1
5 files changed, 55 insertions, 31 deletions
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 6251949a..d1f03288 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -52,6 +52,7 @@
<string name="setup_error_configure_button">Configure</string>
<string name="setup_error_close_button">Exit</string>
<string name="setup_error_text">There was an error configuring %s with your chosen provider.\n\nYou may choose to reconfigure, or exit and configure a provider upon next launch.</string>
+ <string name="setup_error_text_custom">There was an error configuring %s.\n\nYou may choose to reconfigure, or exit.</string>
<string name="server_unreachable_message">The server is unreachable, please try again.</string>
<string name="error.security.pinnedcertificate">Security error, upgrade the app or choose another provider.</string>
<string name="malformed_url">It doesn\'t seem to be a %s provider.</string>
diff --git a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java
index 5416b1f8..d1de62a0 100644
--- a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java
+++ b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java
@@ -35,9 +35,7 @@ import okhttp3.OkHttpClient;
import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.base.models.Provider;
import se.leap.bitmaskclient.base.utils.ConfigHelper;
-import se.leap.bitmaskclient.base.utils.PreferenceHelper;
import se.leap.bitmaskclient.eip.EIP;
-import se.leap.bitmaskclient.eip.EipStatus;
import se.leap.bitmaskclient.providersetup.connectivity.OkHttpClientGenerator;
import se.leap.bitmaskclient.tor.TorStatusObservable;
@@ -47,12 +45,14 @@ import static se.leap.bitmaskclient.R.string.downloading_vpn_certificate_failed;
import static se.leap.bitmaskclient.R.string.error_io_exception_user_message;
import static se.leap.bitmaskclient.R.string.malformed_url;
import static se.leap.bitmaskclient.R.string.setup_error_text;
+import static se.leap.bitmaskclient.R.string.setup_error_text_custom;
import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_cert;
import static se.leap.bitmaskclient.R.string.warning_corrupted_provider_details;
import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_RESULT_KEY;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.base.utils.ConfigHelper.getProviderFormattedString;
+import static se.leap.bitmaskclient.base.utils.ConfigHelper.isDefaultBitmask;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORS;
import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_CERTIFICATE_PINNING;
import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_CORRUPTED_PROVIDER_JSON;
@@ -121,7 +121,7 @@ public class ProviderApiManager extends ProviderApiManagerBase {
}
if (provider.hasEIP() && !provider.allowsRegistered() && !provider.allowsAnonymous()) {
- setErrorResult(currentDownload, setup_error_text, null);
+ setErrorResult(currentDownload, isDefaultBitmask() ? setup_error_text : setup_error_text_custom, null);
}
}
diff --git a/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java b/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java
index f3fd5dbb..4b523edb 100644
--- a/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java
+++ b/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java
@@ -54,6 +54,7 @@ import se.leap.bitmaskclient.testutils.MockSharedPreferences;
import se.leap.bitmaskclient.tor.TorStatusObservable;
import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_RESULT_KEY;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY;
@@ -78,7 +79,7 @@ import static se.leap.bitmaskclient.testutils.BackendMockResponses.BackendMockPr
import static se.leap.bitmaskclient.testutils.MockHelper.mockBundle;
import static se.leap.bitmaskclient.testutils.MockHelper.mockClientGenerator;
import static se.leap.bitmaskclient.testutils.MockHelper.mockConfigHelper;
-import static se.leap.bitmaskclient.testutils.MockHelper.mockFingerprintForCertificate;
+import static se.leap.bitmaskclient.testutils.MockHelper.mockConfigHelper;
import static se.leap.bitmaskclient.testutils.MockHelper.mockIntent;
import static se.leap.bitmaskclient.testutils.MockHelper.mockPreferenceHelper;
import static se.leap.bitmaskclient.testutils.MockHelper.mockProviderApiConnector;
@@ -187,7 +188,7 @@ public class ProviderApiManagerTest {
public void test_handleIntentSetupProvider_happyPath_preseededProviderAndCA() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
Provider provider = getConfiguredProvider();
- mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(NO_ERROR);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
Bundle expectedResult = mockBundle();
@@ -208,7 +209,7 @@ public class ProviderApiManagerTest {
public void test_handleIntentSetupProvider_happyPath_no_preseededProviderAndCA() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
Provider provider = getConfiguredProvider();
- mockFingerprintForCertificate("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(NO_ERROR);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
Bundle expectedResult = mockBundle();
@@ -251,7 +252,7 @@ public class ProviderApiManagerTest {
@Test
public void test_handleIntentSetupProvider_preseededProviderAndCA_failedCAPinning() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
Provider provider = getConfiguredProvider();
- mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29495");
+ mockConfigHelper(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29495");
mockProviderApiConnector(NO_ERROR);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
Bundle expectedResult = mockBundle();
@@ -272,7 +273,7 @@ public class ProviderApiManagerTest {
@Test
public void test_handleIntentSetupProvider_no_preseededProviderAndCA_failedPinning() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
Provider provider = new Provider("https://riseup.net");
- mockFingerprintForCertificate("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29495");
+ mockConfigHelper("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29495");
mockProviderApiConnector(NO_ERROR);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
@@ -417,7 +418,7 @@ public class ProviderApiManagerTest {
Provider provider = getConfiguredProvider();
- mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(ERROR_CASE_MICONFIGURED_PROVIDER);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
@@ -437,11 +438,37 @@ public class ProviderApiManagerTest {
}
@Test
+ public void test_handleIntentSetupProvider_preseededCustomProviderAndCA_failedConfiguration() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
+
+ Provider provider = getConfiguredProvider();
+
+ mockProviderApiConnector(ERROR_CASE_MICONFIGURED_PROVIDER);
+ mockConfigHelper("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ when(ConfigHelper.isDefaultBitmask()).thenReturn(false);
+
+ providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
+
+ Bundle expectedResult = mockBundle();
+ expectedResult.putBoolean(BROADCAST_RESULT_KEY, false);
+ expectedResult.putString(ERRORS, "{\"errors\":\"There was an error configuring RiseupVPN.\"}");
+ expectedResult.putParcelable(PROVIDER_KEY, provider);
+
+
+ Intent providerApiCommand = mockIntent();
+
+ providerApiCommand.putExtra(PROVIDER_KEY, provider);
+ providerApiCommand.setAction(ProviderAPI.SET_UP_PROVIDER);
+ providerApiCommand.putExtra(ProviderAPI.RECEIVER_KEY, mockResultReceiver(PROVIDER_NOK, expectedResult));
+
+ providerApiManager.handleIntent(providerApiCommand);
+ }
+
+ @Test
public void test_handleIntentSetupProvider_outdatedPreseededProviderAndCA_successfulConfiguration() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
Provider provider = getProvider(null, null, null, null, null, "riseup_net_outdated_config.json", null, null);
- mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(NO_ERROR);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
@@ -467,7 +494,7 @@ public class ProviderApiManagerTest {
Provider provider = new Provider("https://riseup.net");
- mockFingerprintForCertificate("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(ERROR_CASE_FETCH_EIP_SERVICE_CERTIFICATE_INVALID);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
@@ -495,7 +522,7 @@ public class ProviderApiManagerTest {
Provider inputProvider = getConfiguredProvider();
inputProvider.setGeoIpJson(new JSONObject());
Provider expectedProvider = getConfiguredProvider();
- mockFingerprintForCertificate("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(NO_ERROR);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
@@ -525,7 +552,7 @@ public class ProviderApiManagerTest {
}
Provider provider = getConfiguredProvider();
- mockFingerprintForCertificate("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(ERROR_GEOIP_SERVICE_IS_DOWN);
mockPreferences.edit().putBoolean(USE_BRIDGES, false).putBoolean(USE_SNOWFLAKE, false).commit();
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
@@ -556,7 +583,7 @@ public class ProviderApiManagerTest {
mockTorStatusObservable(null);
Provider provider = getConfiguredProvider();
- mockFingerprintForCertificate("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(ERROR_GEOIP_SERVICE_IS_DOWN_TOR_FALLBACK);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
@@ -588,7 +615,7 @@ public class ProviderApiManagerTest {
Provider provider = getConfiguredProvider();
provider.setLastGeoIpUpdate(System.currentTimeMillis());
- mockFingerprintForCertificate("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(NO_ERROR);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
@@ -618,7 +645,7 @@ public class ProviderApiManagerTest {
Provider provider = getConfiguredProvider();
provider.setGeoipUrl(null);
provider.setGeoIpJson(new JSONObject());
- mockFingerprintForCertificate("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(NO_ERROR);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
@@ -643,7 +670,7 @@ public class ProviderApiManagerTest {
public void test_handleIntentSetupProvider_APIv4_happyPath() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
Provider provider = getConfiguredProviderAPIv4();
- mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(NO_ERROR_API_V4);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
Bundle expectedResult = mockBundle();
@@ -668,7 +695,7 @@ public class ProviderApiManagerTest {
public void test_handleIntentSetupProvider_TorFallback_SecondTryHappyPath() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, TimeoutException, InterruptedException {
Provider provider = getConfiguredProviderAPIv4();
- mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(ERROR_DNS_RESUOLUTION_TOR_FALLBACK);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
@@ -690,7 +717,7 @@ public class ProviderApiManagerTest {
public void test_handleIntentSetupProvider_TorFallbackStartServiceException_SecondTryFailed() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, TimeoutException, InterruptedException {
Provider provider = getConfiguredProviderAPIv4();
- mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(ERROR_DNS_RESUOLUTION_TOR_FALLBACK);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback(new IllegalStateException("Tor service start not failed."), true));
@@ -709,7 +736,7 @@ public class ProviderApiManagerTest {
public void test_handleIntentSetupProvider_TorFallbackTimeoutException_SecondTryFailed() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, TimeoutException, InterruptedException {
Provider provider = getConfiguredProviderAPIv4();
- mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(ERROR_DNS_RESUOLUTION_TOR_FALLBACK);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback());
@@ -728,7 +755,7 @@ public class ProviderApiManagerTest {
public void test_handleIntentSetupProvider_TorBridgesPreferenceEnabled_Success() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, TimeoutException, InterruptedException {
Provider provider = getConfiguredProviderAPIv4();
- mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(NO_ERROR_API_V4);
mockPreferences.edit().putBoolean(USE_BRIDGES, true).putBoolean(USE_SNOWFLAKE, true).commit();
@@ -749,7 +776,7 @@ public class ProviderApiManagerTest {
public void test_handleIntentSetupProvider_TorBridgesDisabled_TorNotStarted() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, TimeoutException, InterruptedException {
Provider provider = getConfiguredProviderAPIv4();
- mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(NO_ERROR_API_V4);
mockPreferences.edit().putBoolean(USE_BRIDGES, false).putBoolean(USE_SNOWFLAKE, false).commit();
@@ -793,7 +820,7 @@ public class ProviderApiManagerTest {
public void test_handleIntentSetupProvider_noNetwork_NetworkError() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, JSONException {
Provider provider = getConfiguredProvider();
- mockFingerprintForCertificate("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
+ mockConfigHelper("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494");
mockProviderApiConnector(NO_ERROR);
providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback(null, false));
Bundle expectedResult = mockBundle();
diff --git a/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java b/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
index f80f41ed..8d76fd41 100644
--- a/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
+++ b/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java
@@ -416,6 +416,7 @@ public class MockHelper {
when(ConfigHelper.getProviderFormattedString(any(Resources.class), anyInt())).thenCallRealMethod();
when(ConfigHelper.timezoneDistance(anyInt(), anyInt())).thenCallRealMethod();
when(ConfigHelper.isIPv4(anyString())).thenCallRealMethod();
+ when(ConfigHelper.isDefaultBitmask()).thenReturn(true);
}
public static void mockPreferenceHelper(final Provider providerFromPrefs) {
@@ -502,14 +503,6 @@ public class MockHelper {
when(ProviderObservable.getInstance()).thenAnswer((Answer<ProviderObservable>) invocation -> observable);
}
- public static void mockFingerprintForCertificate(String mockedFingerprint) throws CertificateEncodingException, NoSuchAlgorithmException {
- mockStatic(ConfigHelper.class);
- when(ConfigHelper.getFingerprintFromCertificate(any(X509Certificate.class), anyString())).thenReturn(mockedFingerprint);
- when(ConfigHelper.checkErroneousDownload(anyString())).thenCallRealMethod();
- when(ConfigHelper.parseX509CertificatesFromString(anyString())).thenCallRealMethod();
- when(ConfigHelper.getProviderFormattedString(any(Resources.class), anyInt())).thenCallRealMethod();
- }
-
public static void mockProviderApiConnector(final BackendMockProvider.TestBackendErrorCase errorCase) throws IOException {
BackendMockProvider.provideBackendResponsesFor(errorCase);
}
@@ -568,6 +561,8 @@ public class MockHelper {
thenReturn(String.format(errorMessages.getString("warning_expired_provider_cert"), "Bitmask"));
when(mockedResources.getString(eq(R.string.setup_error_text), anyString())).
thenReturn(String.format(errorMessages.getString("setup_error_text"), "Bitmask"));
+ when(mockedResources.getString(eq(R.string.setup_error_text_custom), anyString())).
+ thenReturn(String.format(errorMessages.getString("setup_error_text_custom"), "RiseupVPN"));
when(mockedResources.getString(R.string.app_name)).
thenReturn("Bitmask");
when(mockedResources.getString(eq(R.string.error_tor_timeout), anyString())).
diff --git a/app/src/test/resources/error_messages.json b/app/src/test/resources/error_messages.json
index ae04bdb0..f5e2d83c 100644
--- a/app/src/test/resources/error_messages.json
+++ b/app/src/test/resources/error_messages.json
@@ -14,6 +14,7 @@
"warning_corrupted_provider_cert": "Stored provider certificate is invalid. You can either update %s (recommended) or update the provider certificate using a commercial CA certificate.",
"warning_expired_provider_cert": "Stored provider certificate is expired. You can either update %s (recommended) or update the provider certificate using a commercial CA certificate.",
"setup_error_text": "There was an error configuring %s with your chosen provider.",
+ "setup_error_text_custom": "There was an error configuring %s.",
"error_tor_timeout": "Starting bridges failed. Do you want to retry or continue with an unobfuscated secure connection to configure %s?",
"error_network_connection": "%s has no internet connection. Please check your WiFi and cellular data settings."
} \ No newline at end of file