summaryrefslogtreecommitdiff
path: root/app/src
diff options
context:
space:
mode:
authorcyberta <cyberta@riseup.net>2023-04-12 08:12:07 +0000
committercyberta <cyberta@riseup.net>2023-04-12 08:12:07 +0000
commita4deca391ce064510002e24ba9f18d965f0dee59 (patch)
tree2ffe0d6b6fbbe8c9994e12d00273b10c827b9d2a /app/src
parent49adad2fabcee3077be729064409bfcfbc99fe01 (diff)
parentbf797d855bb55f325e2fb647ac0690aabc62772f (diff)
Merge branch 'improve_fastlane' into 'master'
improve fastlane See merge request leap/bitmask_android!244
Diffstat (limited to 'app/src')
-rw-r--r--app/src/androidTest/java/se/leap/bitmaskclient/base/ProviderBaseTest.java21
-rw-r--r--app/src/androidTestCustom/java/se/leap/bitmaskclient/base/CustomProviderTest.java15
-rw-r--r--app/src/debug/AndroidManifest.xml17
-rw-r--r--app/src/debug/java/se/leap/bitmaskclient/LeakCanaryInstaller.java60
-rw-r--r--app/src/main/AndroidManifest.xml3
-rw-r--r--app/src/test/resources/v4/riseup.net.cert96
6 files changed, 157 insertions, 55 deletions
diff --git a/app/src/androidTest/java/se/leap/bitmaskclient/base/ProviderBaseTest.java b/app/src/androidTest/java/se/leap/bitmaskclient/base/ProviderBaseTest.java
index bbfcdc8b..26cd8699 100644
--- a/app/src/androidTest/java/se/leap/bitmaskclient/base/ProviderBaseTest.java
+++ b/app/src/androidTest/java/se/leap/bitmaskclient/base/ProviderBaseTest.java
@@ -14,22 +14,25 @@ import static androidx.test.espresso.matcher.ViewMatchers.withTagValue;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.anything;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.hasToString;
import static org.hamcrest.Matchers.is;
import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
import static utils.CustomInteractions.tryResolve;
+import android.app.Instrumentation;
import android.content.SharedPreferences;
+import android.net.VpnService;
import android.view.Gravity;
-import androidx.test.espresso.DataInteraction;
-import androidx.test.espresso.NoMatchingViewException;
import androidx.test.espresso.ViewInteraction;
import androidx.test.espresso.contrib.DrawerActions;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject;
+import androidx.test.uiautomator.UiObjectNotFoundException;
+import androidx.test.uiautomator.UiSelector;
import org.junit.Before;
import org.junit.ClassRule;
@@ -56,15 +59,18 @@ public abstract class ProviderBaseTest {
public ActivityScenarioRule<StartActivity> mActivityScenarioRule =
new ActivityScenarioRule<>(StartActivity.class);
+ UiDevice device;
@Before
public void setup() {
Screengrab.setDefaultScreenshotStrategy(new UiAutomatorScreenshotStrategy());
SharedPreferences preferences = getApplicationContext().getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
preferences.edit().clear().commit();
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ device = UiDevice.getInstance(instrumentation);
}
@Test
- public void test01_vpnStartTest() throws InterruptedException {
+ public void test01_vpnStartTest() throws InterruptedException, UiObjectNotFoundException {
boolean configurationNeeded = configureProviderIfNeeded();
ViewInteraction mainButtonStop;
@@ -87,6 +93,11 @@ public abstract class ProviderBaseTest {
20);
Screengrab.screenshot("VPN_connected");
} else {
+ // handle VPN permission dialog
+ if (VpnService.prepare(getApplicationContext()) != null) {
+ UiObject okButton = device.findObject(new UiSelector().packageName("com.android.vpndialogs").resourceId("android:id/button1"));
+ okButton.click();
+ }
// on new configurations the VPN is automatically started
Screengrab.screenshot("VPN_connecting");
mainButtonStop = tryResolve(
diff --git a/app/src/androidTestCustom/java/se/leap/bitmaskclient/base/CustomProviderTest.java b/app/src/androidTestCustom/java/se/leap/bitmaskclient/base/CustomProviderTest.java
index 1a0814b6..92416af4 100644
--- a/app/src/androidTestCustom/java/se/leap/bitmaskclient/base/CustomProviderTest.java
+++ b/app/src/androidTestCustom/java/se/leap/bitmaskclient/base/CustomProviderTest.java
@@ -1,5 +1,6 @@
package se.leap.bitmaskclient.base;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
@@ -9,7 +10,12 @@ import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static utils.CustomInteractions.tryResolve;
+import android.net.VpnService;
+
import androidx.test.espresso.ViewInteraction;
+import androidx.test.uiautomator.UiObject;
+import androidx.test.uiautomator.UiObjectNotFoundException;
+import androidx.test.uiautomator.UiSelector;
import org.junit.Test;
@@ -20,7 +26,14 @@ public class CustomProviderTest extends ProviderBaseTest {
@Test
@Override
- public void test01_vpnStartTest() throws InterruptedException {
+ public void test01_vpnStartTest() throws InterruptedException, UiObjectNotFoundException {
+ // handle VPN permission dialog
+ if (VpnService.prepare(getApplicationContext()) != null) {
+ UiObject okButton = device.findObject(new UiSelector().packageName("com.android.vpndialogs").resourceId("android:id/button1"));
+ okButton.waitForExists(30000);
+ okButton.click();
+ }
+
ViewInteraction mainButtonStop;
mainButtonStop = tryResolve(
onView(withId(R.id.main_button)),
diff --git a/app/src/debug/AndroidManifest.xml b/app/src/debug/AndroidManifest.xml
index 51e17015..08062ff3 100644
--- a/app/src/debug/AndroidManifest.xml
+++ b/app/src/debug/AndroidManifest.xml
@@ -19,6 +19,23 @@
package="se.leap.bitmaskclient"
android:requestLegacyExternalStorage="true"
>
+
+ <application
+ android:name=".base.BitmaskApp"
+ android:allowBackup="true"
+ android:icon="@mipmap/ic_launcher"
+ android:label="@string/app_name"
+ android:extractNativeLibs="true"
+ android:appCategory="productivity"
+ android:logo="@mipmap/ic_launcher"
+ android:theme="@style/BitmaskTheme">
+ >
+ <provider
+ android:name=".LeakCanaryInstaller"
+ android:authorities="${applicationId}.leakcanary-installer"
+ android:exported="false" />
+ </application>
+
<!-- package is overwritten in build.gradle -->
<!-- The following permissions are required by fastlane / espresso -->
diff --git a/app/src/debug/java/se/leap/bitmaskclient/LeakCanaryInstaller.java b/app/src/debug/java/se/leap/bitmaskclient/LeakCanaryInstaller.java
new file mode 100644
index 00000000..25b94ef2
--- /dev/null
+++ b/app/src/debug/java/se/leap/bitmaskclient/LeakCanaryInstaller.java
@@ -0,0 +1,60 @@
+package se.leap.bitmaskclient;
+
+import android.app.Application;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import leakcanary.AppWatcher;
+
+public class LeakCanaryInstaller extends ContentProvider {
+
+ @Override
+ public boolean onCreate() {
+ if (!isTest()) {
+ AppWatcher.INSTANCE.manualInstall((Application)getContext().getApplicationContext());
+ }
+ return false;
+ }
+
+ @Nullable
+ @Override
+ public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public String getType(@NonNull Uri uri) {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
+ return null;
+ }
+
+ @Override
+ public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
+ return 0;
+ }
+
+ @Override
+ public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
+ return 0;
+ }
+
+
+ private boolean isTest() {
+ try {
+ return Class.forName("org.junit.Test") != null;
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6a9de68d..5d221529 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
package="se.leap.bitmaskclient">
<!-- package is overwritten in build.gradle -->
@@ -26,7 +27,7 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
- android:maxSdkVersion="18"/>
+ tools:ignore="ScopedStorage" />
<!-- Used to show all apps in the allowed Apps selection -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
diff --git a/app/src/test/resources/v4/riseup.net.cert b/app/src/test/resources/v4/riseup.net.cert
index 2708a8c8..e8c0d36f 100644
--- a/app/src/test/resources/v4/riseup.net.cert
+++ b/app/src/test/resources/v4/riseup.net.cert
@@ -1,54 +1,54 @@
-----BEGIN RSA PRIVATE KEY-----
-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
+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
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
-MIIEmzCCAoOgAwIBAgIQcAUo8ZeIKRBNyIAyEg7QFDANBgkqhkiG9w0BAQsFADB1
+MIIEmzCCAoOgAwIBAgIQIKutrfucdU13oecG2QmRBTANBgkqhkiG9w0BAQsFADB1
MRgwFgYDVQQKDA9SaXNldXAgTmV0d29ya3MxGzAZBgNVBAsMEmh0dHBzOi8vcmlz
ZXVwLm5ldDE8MDoGA1UEAwwzUmlzZXVwIE5ldHdvcmtzIFJvb3QgQ0EgKGNsaWVu
-dCBjZXJ0aWZpY2F0ZXMgb25seSEpMB4XDTIyMTIyMDAwMDAwMFoXDTIzMDMyMDAw
-MDAwMFowLTErMCkGA1UEAwwiVU5MSU1JVEVEYnpnMWZicmd3MWdsa29qMWlhZG4w
-d2ZiaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANvaq2cVUM9HK5fV
-Emwac2QjH2w56PLWVYyP4pqi4HX4Jmltg+WBJgzD669xhKlQSgGE/Sx0YJk0outz
-1tzfIG/QijHaELUi9+V3C214LXbCRM0ksgm7V5geGK6djYczEvaoRQI2y4452ZGh
-Ai5mQ5GuXcuo+iVo0TZaROLpqhkgswbWgCF7lIzBd4cmfZGNqI3UQ0qNyP4Hm6Nr
-8GlI/5cGG7NZZA39C1QnMJqS5KacZ3/goE/DAPR0bzpPE2SaUoQD1ljgTVlY4e/T
-heNTAmyAK/cp6zUfIKzkyVee6tVdOPxovlHtAZL8bBrTRsU60uJQuu9mt2fJ1vzQ
-rjJ1Ux8CAwEAAaNvMG0wHQYDVR0OBBYEFF1cHd5fjHXKbGrW0qd4zNg6KquiMAsG
+dCBjZXJ0aWZpY2F0ZXMgb25seSEpMB4XDTIzMDIyODAwMDAwMFoXDTIzMDUzMTAw
+MDAwMFowLTErMCkGA1UEAwwiVU5MSU1JVEVENG9oejc5a2dkcDZwYWtvMWZhOXN3
+dGtyOTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMBffi6Q6KL04yok
+033ocMs2gzLXdOfdACv8Iqr6uVQ+QKSw0QhXrC5Byj9ilTZg2ZIah3FDXsz6BgqF
+bnNQ3tPQf+ubf1RJMLd0pB5uz/mzMFy/ZsfV08wUztFP+j0cpd++PkJg6NnWqUi/
+ioZ3C8ca0W24+lNeW/0NwGwF7jWMi4I0sKpVgH6G/A1r/6JTdMR9Pif5ulh/03zU
+eaqU03s9Wt9Zq1jg13ZRWcNJAXqWflGN65wkLwzOuEB5jPU7aTiQkFOrh6FuQ7y5
+Kz9w/4AnzW/dqIrUfUGM1+m6tWL5T3QjR6dIY95nO+6fNlQZyoQRDxORG21L4dLq
+CP6Xw/8CAwEAAaNvMG0wHQYDVR0OBBYEFBW4dMo4Un6EVU+I87yL7WSuy9IAMAsG
A1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAjAJBgNVHRMEAjAAMB8GA1Ud
-IwQYMBaAFBf0G9XlKgEBTWuiXTYKKQmWZYBGMA0GCSqGSIb3DQEBCwUAA4ICAQCS
-sDwNJmNqgrOeNgEuszIGE5V2wTj89S2TtHggBfWErKGUn7N0+gcIRvxxCHG9X7ne
-WjhTS/kEMblR3OcaB/8kfBGCZD6Hc+d0nXv7G5Iqpy5eJuWnv8L4n7QUxIkYiyRr
-bp3Mg31MCFKlDVi2RoTbm3rvcWYPsfBARu6tZlvfNb2Q6dP9/zPU1N2b69fyNwXV
-IOjF/5KPt4n/abxyFuty6xv1G9B3Bq072wZrUSQbZsOLNUtSyLJVyhHRLBBzOOJ/
-Cw8awAEeXXwF1+qAO4MAq/ILcA/v8hAR6AlZez6nbZOBfk5JvEPumZPdIQN6PQ6J
-jODFuJRFFemea3uYyUEnv5MD3BcsApIrM7eRc82Edc9a73CkuMP4ekG68OFl2qHl
-h+XzEchQNVG3t+Ka+8FN1RyeXhPRjzf1JG0elP+CIuyHBOd1SJLv4elGK2ZJWk2L
-cPfLt+tFATKy3PEuftXasLG9g/K8PVaNh8gmh4en88vM0XxZ7npygPv84Cl5wV4r
-LUuR6Cy8quE8QHx01D2EAspkHqk4d/xClyxfT1KCKEQvOk5gOlSrEFsB8TTqtYfr
-G1LiVDcwEq+ExmeDwGIW0EY2mOre7yTHva0p0JZ4AcyK4lNIPXpGBOQcyZ++7/jh
-vdNyERG7ZAjCsj7YTy72On5cS6DQDEHnKmrAIejLLw==
------END CERTIFICATE----- \ No newline at end of file
+IwQYMBaAFBf0G9XlKgEBTWuiXTYKKQmWZYBGMA0GCSqGSIb3DQEBCwUAA4ICAQBc
+Ah7+JUyBDDjHJRtRlkIW5jaBMqtIa6D6WXglfMuKaUs2dXYF2DMUFJH8GPEdvazY
+C0IXsZb60WnxSmGxJyAFEe1nWzzZ494lAxSjNmkpCBrqaMISABIvqjCViO5ozZ77
+tKcqZVSjuIQvOtjwsYcTkOn9LR+F1Jzlr8K3mtukhy1U1heYY1EZNH5DMlqDGtyI
+gJfxZiNu1en46Qfx4EenVKCe4pk3RWhXNlv/1XOyRLrz8T7L8LbcOWCkU07N9Qgj
+8SnbzRin/uUNUNjZ00sbcr2NJmmecOZXLz4td/+sGBbONhiPtkU5gbzoXsCUS9Fd
+li0lHDmj4aso934eWwS5xUi5vii2jqgr7STi99JlDR1x+wT56fbWa1EB9J7GWubh
+jMoyoAq6Fs0fl8p+vLSft4TYj/mXcvXJbIPZjqk1oTXm7wGJnh7uXA1NPRS69pUr
++Z7xEjDXN0SN81xFEBZx7CHXxOlMRa8e9Ch6EvxWfUzzT18rsNpWhYW6XikMFvuQ
+XXDg2vnqXQa5JvOZrmeQ4HqDa+7lm8jBbpPJpWasTE+ebBlHEkaxBBxYqi6/bxXJ
+xNGx9hJA8yoVwURAYkQ8zgfjjx3lEd0zzlRn0sVYWIBxamHisqNRwV1z4iFZIEdQ
+rDc9567yE4enRLKcSEv+aeW/N8pf57sWur0fjUOPbw==
+-----END CERTIFICATE-----