Prechádzať zdrojové kódy

Merge pull request #6452 from nextcloud/dialogTests

Add tests for dialogs
Andy Scherzinger 4 rokov pred
rodič
commit
cc1c4e9b11
42 zmenil súbory, kde vykonal 465 pridanie a 153 odobranie
  1. 3 43
      .drone.yml
  2. BIN
      screenshots/gplay/debug/com.nextcloud.client.ActivitiesActivityIT_openDrawer.png
  3. BIN
      screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityIT_drawer.png
  4. BIN
      screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityIT_open.png
  5. BIN
      screenshots/gplay/debug/com.nextcloud.client.NotificationsActivityIT_openDrawer.png
  6. BIN
      screenshots/gplay/debug/com.nextcloud.client.SettingsActivityIT_open.png
  7. BIN
      screenshots/gplay/debug/com.nextcloud.client.SyncedFoldersActivityIT_openDrawer.png
  8. BIN
      screenshots/gplay/debug/com.nextcloud.client.SyncedFoldersActivityIT_testSyncedFolderDialog.png
  9. BIN
      screenshots/gplay/debug/com.nextcloud.client.UploadListActivityActivityIT_openDrawer.png
  10. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_keepBoth.png
  11. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_keepExisting.png
  12. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_keepNew.png
  13. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_screenshotTextFiles.png
  14. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.activity.ManageAccountsActivityIT_open.png
  15. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.activity.ManageAccountsActivityIT_userInfoDetail.png
  16. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog.png
  17. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testLoadingDialog.png
  18. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFileDialog.png
  19. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFilesDialog.png
  20. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFolderDialog.png
  21. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFoldersDialog.png
  22. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testAccountChooserDialog.png
  23. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testLoadingDialog.png
  24. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testNewFolderDialog.png
  25. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testRemoveFileDialog.png
  26. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testRemoveFilesDialog.png
  27. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testRemoveFolderDialog.png
  28. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testRemoveFoldersDialog.png
  29. BIN
      screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testRenameFileDialog.png
  30. 1 1
      src/androidTest/java/com/nextcloud/client/FileDisplayActivityIT.java
  31. 1 1
      src/androidTest/java/com/nextcloud/client/RetryTestRule.kt
  32. 40 0
      src/androidTest/java/com/nextcloud/client/SyncedFoldersActivityIT.java
  33. 8 95
      src/androidTest/java/com/owncloud/android/AbstractIT.java
  34. 229 0
      src/androidTest/java/com/owncloud/android/AbstractOnServerIT.java
  35. 2 2
      src/androidTest/java/com/owncloud/android/datamodel/FileDataStorageManagerTest.java
  36. 6 0
      src/androidTest/java/com/owncloud/android/ui/activity/ConflictsResolveActivityIT.java
  37. 160 0
      src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.java
  38. 4 5
      src/androidTest/java/com/owncloud/android/ui/fragment/OCFileListFragmentIT.kt
  39. 2 3
      src/androidTest/java/com/owncloud/android/ui/preview/PreviewTextFileFragmentTest.java
  40. 3 1
      src/main/java/com/nextcloud/ui/ChooseAccountDialogFragment.kt
  41. 5 1
      src/main/java/com/owncloud/android/ui/adapter/UserListAdapter.java
  42. 1 1
      src/main/res/layout/account_item.xml

+ 3 - 43
.drone.yml

@@ -22,6 +22,7 @@ steps:
       - emulator-headless -avd android-27 -no-snapshot -gpu swiftshader_indirect -no-window -no-audio -skin 500x833 &
       - sed -i s'#<bool name="is_beta">false</bool>#<bool name="is_beta">true</bool>#'g src/main/res/values/setup.xml
       - sed -i s"#server#server#" gradle.properties
+      - sed -i s"#1#5#" ./src/androidTest/java/com/nextcloud/client/RetryTestRule.kt
       - ./gradlew assembleGplay
       - ./gradlew assembleGplayDebug
       - scripts/wait_for_emulator.sh
@@ -101,6 +102,7 @@ steps:
       - scripts/checkIfRunDrone.sh $GIT_USERNAME $GIT_TOKEN $DRONE_PULL_REQUEST || exit 0
       - emulator-headless -avd android-27 -no-snapshot -gpu swiftshader_indirect -no-window -no-audio -skin 500x833 &
       - sed -i s'#<bool name="is_beta">false</bool>#<bool name="is_beta">true</bool>#'g src/main/res/values/setup.xml
+      - sed -i s"#1#5#" ./src/androidTest/java/com/nextcloud/client/RetryTestRule.kt
       - ./gradlew assembleGplay
       - ./gradlew assembleGplayDebug
       - scripts/wait_for_emulator.sh
@@ -186,7 +188,6 @@ steps:
       - ./gradlew assembleGplayDebug
       - scripts/wait_for_emulator.sh
       - ./gradlew installGplayDebugAndroidTest
-      - scripts/wait_for_server.sh "server"
       - ./gradlew gplayDebugExecuteScreenshotTests -Pandroid.testInstrumentationRunnerArguments.annotation=com.owncloud.android.utils.ScreenshotTest && scripts/deleteOutdatedComments.sh "stable" "Screenshot" $DRONE_PULL_REQUEST $GIT_USERNAME $GIT_TOKEN || scripts/uploadReport.sh $LOG_USERNAME $LOG_PASSWORD $DRONE_BUILD_NUMBER "stable" "Screenshot" $DRONE_PULL_REQUEST $GIT_USERNAME $GIT_TOKEN
   - name: notify
     image: drillster/drone-email
@@ -209,26 +210,6 @@ steps:
         - failure
       branch:
         - master
-
-services:
-  - name: server
-    image: nextcloudci/server:server-17 # also change in updateScreenshots.sh
-    commands:
-      - BRANCH='stable18' /usr/local/bin/initnc.sh
-      - su www-data -c "OC_PASS=user1 php /var/www/html/occ user:add --password-from-env --display-name='User One' user1"
-      - su www-data -c "OC_PASS=user2 php /var/www/html/occ user:add --password-from-env --display-name='User Two' user2"
-      - su www-data -c "OC_PASS=user3 php /var/www/html/occ user:add --password-from-env --display-name='User Three' user3"
-      - su www-data -c "php /var/www/html/occ user:setting user2 files quota 1G"
-      - su www-data -c "php /var/www/html/occ group:add users"
-      - su www-data -c "php /var/www/html/occ group:adduser users user1"
-      - su www-data -c "php /var/www/html/occ group:adduser users user2"
-      - su www-data -c "git clone -b stable18 https://github.com/nextcloud/activity.git /var/www/html/apps/activity/"
-      - su www-data -c "php /var/www/html/occ app:enable activity"
-      - su www-data -c "git clone -b stable18 https://github.com/nextcloud/text.git /var/www/html/apps/text/"
-      - su www-data -c "php /var/www/html/occ app:enable text"
-      - su www-data -c "php /var/www/html/occ app:enable end_to_end_encryption"
-      - /usr/local/bin/run.sh
-
 trigger:
   branch:
     - master
@@ -261,7 +242,7 @@ steps:
       - ./gradlew assembleGplayDebug
       - scripts/wait_for_emulator.sh
       - ./gradlew installGplayDebugAndroidTest
-      - scripts/wait_for_server.sh "server"
+      - sed -i s"#5#1#" ./src/androidTest/java/com/nextcloud/client/RetryTestRule.kt
       - ./gradlew gplayDebugExecuteScreenshotTests -Pandroid.testInstrumentationRunnerArguments.annotation=com.owncloud.android.utils.ScreenshotTest && scripts/deleteOutdatedComments.sh "master" "Screenshot" $DRONE_PULL_REQUEST $GIT_USERNAME $GIT_TOKEN || scripts/uploadReport.sh $LOG_USERNAME $LOG_PASSWORD $DRONE_BUILD_NUMBER "master" "Screenshot" $DRONE_PULL_REQUEST $GIT_USERNAME $GIT_TOKEN
   - name: notify
     image: drillster/drone-email
@@ -284,27 +265,6 @@ steps:
         - failure
       branch:
         - master
-
-services:
-  - name: server
-    image: nextcloudci/server:server-17 # also change in updateScreenshots.sh
-    commands:
-      - /usr/local/bin/initnc.sh
-      - su www-data -c "OC_PASS=user1 php /var/www/html/occ user:add --password-from-env --display-name='User One' user1"
-      - su www-data -c "OC_PASS=user2 php /var/www/html/occ user:add --password-from-env --display-name='User Two' user2"
-      - su www-data -c "OC_PASS=user3 php /var/www/html/occ user:add --password-from-env --display-name='User Three' user3"
-      - su www-data -c "php /var/www/html/occ user:setting user2 files quota 1G"
-      - su www-data -c "php /var/www/html/occ group:add users"
-      - su www-data -c "php /var/www/html/occ group:adduser users user1"
-      - su www-data -c "php /var/www/html/occ group:adduser users user2"
-      - su www-data -c "git clone -b master https://github.com/nextcloud/activity.git /var/www/html/apps/activity/"
-      - su www-data -c "php /var/www/html/occ app:enable activity"
-      - su www-data -c "git clone -b master https://github.com/nextcloud/text.git /var/www/html/apps/text/"
-      - su www-data -c "php /var/www/html/occ app:enable text"
-      - su www-data -c "git clone -b master https://github.com/nextcloud/end_to_end_encryption/  /var/www/html/apps/end_to_end_encryption/"
-      - su www-data -c "php /var/www/html/occ app:enable end_to_end_encryption"
-      - /usr/local/bin/run.sh
-
 trigger:
   branch:
     - master

BIN
screenshots/gplay/debug/com.nextcloud.client.ActivitiesActivityIT_openDrawer.png


BIN
screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityIT_drawer.png


BIN
screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityIT_open.png


BIN
screenshots/gplay/debug/com.nextcloud.client.NotificationsActivityIT_openDrawer.png


BIN
screenshots/gplay/debug/com.nextcloud.client.SettingsActivityIT_open.png


BIN
screenshots/gplay/debug/com.nextcloud.client.SyncedFoldersActivityIT_openDrawer.png


BIN
screenshots/gplay/debug/com.nextcloud.client.SyncedFoldersActivityIT_testSyncedFolderDialog.png


BIN
screenshots/gplay/debug/com.nextcloud.client.UploadListActivityActivityIT_openDrawer.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_keepBoth.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_keepExisting.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_keepNew.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.activity.ConflictsResolveActivityIT_screenshotTextFiles.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.activity.ManageAccountsActivityIT_open.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.activity.ManageAccountsActivityIT_userInfoDetail.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testLoadingDialog.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFileDialog.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFilesDialog.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFolderDialog.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testRemoveFoldersDialog.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testAccountChooserDialog.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testLoadingDialog.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testNewFolderDialog.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testRemoveFileDialog.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testRemoveFilesDialog.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testRemoveFolderDialog.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testRemoveFoldersDialog.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentTest_testRenameFileDialog.png


+ 1 - 1
src/androidTest/java/com/nextcloud/client/FileDisplayActivityIT.java

@@ -90,7 +90,7 @@ public class FileDisplayActivityIT extends AbstractIT {
     }
 
     @Test
-    @ScreenshotTest
+    // @ScreenshotTest // todo run without real server
     public void showShares() {
         assertTrue(new ExistenceCheckRemoteOperation("/shareToAdmin/", true).execute(client).isSuccess());
         assertTrue(new CreateFolderRemoteOperation("/shareToAdmin/", true).execute(client).isSuccess());

+ 1 - 1
src/androidTest/java/com/nextcloud/client/RetryTestRule.kt

@@ -30,7 +30,7 @@ import org.junit.runners.model.Statement
 /**
  * C&p from https://stackoverflow.com/questions/45635833/how-can-i-use-flakytest-annotation-now on 18.03.2020
  */
-class RetryTestRule(val retryCount: Int = 5) : TestRule {
+class RetryTestRule(val retryCount: Int = 1) : TestRule {
 
     companion object {
         private val TAG = RetryTestRule::class.java.simpleName

+ 40 - 0
src/androidTest/java/com/nextcloud/client/SyncedFoldersActivityIT.java

@@ -23,17 +23,26 @@
 package com.nextcloud.client;
 
 import android.Manifest;
+import android.content.Intent;
 
+import com.facebook.testing.screenshot.Screenshot;
 import com.owncloud.android.AbstractIT;
+import com.owncloud.android.datamodel.MediaFolderType;
+import com.owncloud.android.datamodel.SyncedFolderDisplayItem;
 import com.owncloud.android.ui.activity.SyncedFoldersActivity;
+import com.owncloud.android.ui.dialog.SyncedFolderPreferencesDialogFragment;
 import com.owncloud.android.utils.ScreenshotTest;
 
 import org.junit.Rule;
 import org.junit.Test;
 
+import java.util.Objects;
+
 import androidx.test.espresso.intent.rule.IntentsTestRule;
 import androidx.test.rule.GrantPermissionRule;
 
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
 
 public class SyncedFoldersActivityIT extends AbstractIT {
     @Rule public IntentsTestRule<SyncedFoldersActivity> activityRule = new IntentsTestRule<>(SyncedFoldersActivity.class,
@@ -49,4 +58,35 @@ public class SyncedFoldersActivityIT extends AbstractIT {
     public void openDrawer() {
         super.openDrawer(activityRule);
     }
+
+    @Test
+    @ScreenshotTest
+    public void testSyncedFolderDialog() {
+        SyncedFolderDisplayItem item = new SyncedFolderDisplayItem(1,
+                                                                   "/sdcard/DCIM/",
+                                                                   "/InstantUpload/",
+                                                                   true,
+                                                                   false,
+                                                                   false,
+                                                                   true,
+                                                                   "test@server.com",
+                                                                   0,
+                                                                   0,
+                                                                   true,
+                                                                   1000,
+                                                                   "Name",
+                                                                   MediaFolderType.IMAGE,
+                                                                   false);
+        SyncedFolderPreferencesDialogFragment sut = SyncedFolderPreferencesDialogFragment.newInstance(item, 0);
+
+        Intent intent = new Intent(targetContext, SyncedFoldersActivity.class);
+        SyncedFoldersActivity activity = activityRule.launchActivity(intent);
+
+        sut.show(activity.getSupportFragmentManager(), "");
+
+        getInstrumentation().waitForIdleSync();
+        shortSleep();
+
+        Screenshot.snap(Objects.requireNonNull(sut.requireDialog().getWindow()).getDecorView()).record();
+    }
 }

+ 8 - 95
src/androidTest/java/com/owncloud/android/AbstractIT.java

@@ -7,8 +7,6 @@ import android.accounts.OperationCanceledException;
 import android.app.Activity;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
-import android.net.Uri;
-import android.os.Bundle;
 
 import com.facebook.testing.screenshot.Screenshot;
 import com.nextcloud.client.RetryTestRule;
@@ -29,21 +27,13 @@ import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.OwnCloudClientFactory;
 import com.owncloud.android.lib.common.accounts.AccountUtils;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
-import com.owncloud.android.lib.resources.e2ee.ToggleEncryptionRemoteOperation;
-import com.owncloud.android.lib.resources.files.ReadFolderRemoteOperation;
-import com.owncloud.android.lib.resources.files.RemoveFileRemoteOperation;
-import com.owncloud.android.lib.resources.files.model.RemoteFile;
 import com.owncloud.android.operations.CreateFolderOperation;
 import com.owncloud.android.operations.UploadFileOperation;
 import com.owncloud.android.utils.FileStorageUtils;
 
 import junit.framework.TestCase;
 
-import org.apache.commons.httpclient.HttpStatus;
-import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.commons.io.FileUtils;
-import org.junit.After;
-import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Rule;
 
@@ -78,7 +68,7 @@ public abstract class AbstractIT {
     protected static User user;
     protected static Context targetContext;
 
-    private Activity currentActivity;
+    protected Activity currentActivity;
 
     protected FileDataStorageManager fileDataStorageManager =
         new FileDataStorageManager(account, targetContext.getContentResolver());
@@ -87,26 +77,15 @@ public abstract class AbstractIT {
     public static void beforeAll() {
         try {
             targetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
-            Bundle arguments = androidx.test.platform.app.InstrumentationRegistry.getArguments();
-
-            Uri baseUrl = Uri.parse(arguments.getString("TEST_SERVER_URL"));
-            String loginName = arguments.getString("TEST_SERVER_USERNAME");
-            String password = arguments.getString("TEST_SERVER_PASSWORD");
-
-            Account temp = new Account(loginName + "@" + baseUrl, MainApp.getAccountType(targetContext));
-            UserAccountManager accountManager = UserAccountManagerImpl.fromContext(targetContext);
-            if (!accountManager.exists(temp)) {
-                AccountManager platformAccountManager = AccountManager.get(targetContext);
-                platformAccountManager.addAccountExplicitly(temp, password, null);
-                platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_OC_ACCOUNT_VERSION,
-                        Integer.toString(UserAccountManager.ACCOUNT_VERSION));
-                platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_OC_VERSION, "14.0.0.0");
-                platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_OC_BASE_URL, baseUrl.toString());
-                platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_USER_ID, loginName); // same as userId
-            }
+
+            Account temp = new Account("test@server.com", MainApp.getAccountType(targetContext));
+            AccountManager platformAccountManager = AccountManager.get(targetContext);
+            platformAccountManager.addAccountExplicitly(temp, "password", null);
+            platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_OC_BASE_URL, "https://server.com");
+            platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_USER_ID, "test");
 
             final UserAccountManager userAccountManager = UserAccountManagerImpl.fromContext(targetContext);
-            account = userAccountManager.getAccountByName(loginName + "@" + baseUrl);
+            account = userAccountManager.getAccountByName("test@server.com");
 
             if (account == null) {
                 throw new ActivityNotFoundException();
@@ -116,12 +95,6 @@ public abstract class AbstractIT {
             user = optionalUser.orElseThrow(IllegalAccessError::new);
 
             client = OwnCloudClientFactory.createOwnCloudClient(account, targetContext);
-
-            createDummyFiles();
-
-            waitForServer(client, baseUrl);
-
-            deleteAllFiles(); // makes sure that no file/folder is in root
         } catch (OperationCanceledException e) {
             e.printStackTrace();
         } catch (AuthenticatorException e) {
@@ -133,36 +106,6 @@ public abstract class AbstractIT {
         }
     }
 
-    @After
-    public void after() {
-        deleteAllFiles();
-    }
-
-    public static void deleteAllFiles() {
-        RemoteOperationResult result = new ReadFolderRemoteOperation("/").execute(client);
-        assertTrue(result.getLogMessage(), result.isSuccess());
-
-        for (Object object : result.getData()) {
-            RemoteFile remoteFile = (RemoteFile) object;
-
-            if (!remoteFile.getRemotePath().equals("/")) {
-                if (remoteFile.isEncrypted()) {
-                    assertTrue(new ToggleEncryptionRemoteOperation(remoteFile.getLocalId(),
-                                                                   remoteFile.getRemotePath(),
-                                                                   false)
-                                   .execute(client)
-                                   .isSuccess());
-                }
-
-                assertTrue(new RemoveFileRemoteOperation(remoteFile.getRemotePath())
-                               .execute(client)
-                               .isSuccess()
-                          );
-            }
-        }
-    }
-
-
     protected FileDataStorageManager getStorageManager() {
         return fileDataStorageManager;
     }
@@ -171,14 +114,6 @@ public abstract class AbstractIT {
         return AccountManager.get(targetContext).getAccounts();
     }
 
-    private static void createDummyFiles() throws IOException {
-        new File(FileStorageUtils.getSavePath(account.name)).mkdirs();
-
-        createFile("empty.txt", 0);
-        createFile("nonEmpty.txt", 100);
-        createFile("chunkedFile.txt", 500000);
-    }
-
     public static void createFile(String name, int iteration) throws IOException {
         File file = new File(FileStorageUtils.getSavePath(account.name) + File.separator + name);
         file.createNewFile();
@@ -192,28 +127,6 @@ public abstract class AbstractIT {
         writer.close();
     }
 
-    private static void waitForServer(OwnCloudClient client, Uri baseUrl) {
-        GetMethod get = new GetMethod(baseUrl + "/status.php");
-
-        try {
-            int i = 0;
-            while (client.executeMethod(get) != HttpStatus.SC_OK && i < 3) {
-                System.out.println("wait…");
-                Thread.sleep(60 * 1000);
-                i++;
-            }
-
-            if (i == 3) {
-                Assert.fail("Server not ready!");
-            }
-
-        } catch (IOException e) {
-            e.printStackTrace();
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
-    }
-
     protected File getFile(String filename) throws IOException {
         InputStream inputStream = getInstrumentation().getContext().getAssets().open(filename);
         File temp = File.createTempFile("file", "file");

+ 229 - 0
src/androidTest/java/com/owncloud/android/AbstractOnServerIT.java

@@ -0,0 +1,229 @@
+package com.owncloud.android;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.content.ActivityNotFoundException;
+import android.net.Uri;
+import android.os.Bundle;
+
+import com.nextcloud.client.account.UserAccountManager;
+import com.nextcloud.client.account.UserAccountManagerImpl;
+import com.nextcloud.client.device.BatteryStatus;
+import com.nextcloud.client.device.PowerManagementService;
+import com.nextcloud.client.network.Connectivity;
+import com.nextcloud.client.network.ConnectivityService;
+import com.owncloud.android.datamodel.UploadsStorageManager;
+import com.owncloud.android.db.OCUpload;
+import com.owncloud.android.files.services.FileUploader;
+import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.OwnCloudClientFactory;
+import com.owncloud.android.lib.common.accounts.AccountUtils;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.resources.e2ee.ToggleEncryptionRemoteOperation;
+import com.owncloud.android.lib.resources.files.ReadFolderRemoteOperation;
+import com.owncloud.android.lib.resources.files.RemoveFileRemoteOperation;
+import com.owncloud.android.lib.resources.files.model.RemoteFile;
+import com.owncloud.android.operations.UploadFileOperation;
+import com.owncloud.android.utils.FileStorageUtils;
+
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import androidx.annotation.NonNull;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import static org.junit.Assert.assertTrue;
+
+
+/**
+ * Common base for all integration tests
+ */
+
+public abstract class AbstractOnServerIT extends AbstractIT {
+    @BeforeClass
+    public static void beforeAll() {
+        try {
+            targetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+            Bundle arguments = androidx.test.platform.app.InstrumentationRegistry.getArguments();
+
+            Uri baseUrl = Uri.parse(arguments.getString("TEST_SERVER_URL"));
+            String loginName = arguments.getString("TEST_SERVER_USERNAME");
+            String password = arguments.getString("TEST_SERVER_PASSWORD");
+
+            Account temp = new Account(loginName + "@" + baseUrl, MainApp.getAccountType(targetContext));
+            UserAccountManager accountManager = UserAccountManagerImpl.fromContext(targetContext);
+            if (!accountManager.exists(temp)) {
+                AccountManager platformAccountManager = AccountManager.get(targetContext);
+                platformAccountManager.addAccountExplicitly(temp, password, null);
+                platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_OC_ACCOUNT_VERSION,
+                                                   Integer.toString(UserAccountManager.ACCOUNT_VERSION));
+                platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_OC_VERSION, "14.0.0.0");
+                platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_OC_BASE_URL, baseUrl.toString());
+                platformAccountManager.setUserData(temp, AccountUtils.Constants.KEY_USER_ID, loginName); // same as userId
+            }
+
+            final UserAccountManager userAccountManager = UserAccountManagerImpl.fromContext(targetContext);
+            account = userAccountManager.getAccountByName(loginName + "@" + baseUrl);
+
+            if (account == null) {
+                throw new ActivityNotFoundException();
+            }
+
+            client = OwnCloudClientFactory.createOwnCloudClient(account, targetContext);
+
+            createDummyFiles();
+
+            waitForServer(client, baseUrl);
+
+            deleteAllFiles(); // makes sure that no file/folder is in root
+
+        } catch (OperationCanceledException e) {
+            e.printStackTrace();
+        } catch (AuthenticatorException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (AccountUtils.AccountNotFoundException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @After
+    public void after() {
+        deleteAllFiles();
+    }
+
+    public static void deleteAllFiles() {
+        RemoteOperationResult result = new ReadFolderRemoteOperation("/").execute(client);
+        assertTrue(result.getLogMessage(), result.isSuccess());
+
+        for (Object object : result.getData()) {
+            RemoteFile remoteFile = (RemoteFile) object;
+
+            if (!remoteFile.getRemotePath().equals("/")) {
+                if (remoteFile.isEncrypted()) {
+                    assertTrue(new ToggleEncryptionRemoteOperation(remoteFile.getLocalId(),
+                                                                   remoteFile.getRemotePath(),
+                                                                   false)
+                                   .execute(client)
+                                   .isSuccess());
+                }
+
+                assertTrue(new RemoveFileRemoteOperation(remoteFile.getRemotePath())
+                               .execute(client)
+                               .isSuccess()
+                          );
+            }
+        }
+    }
+
+    private static void createDummyFiles() throws IOException {
+        new File(FileStorageUtils.getSavePath(account.name)).mkdirs();
+
+        createFile("empty.txt", 0);
+        createFile("nonEmpty.txt", 100);
+        createFile("chunkedFile.txt", 500000);
+    }
+
+    public static void createFile(String name, int iteration) throws IOException {
+        File file = new File(FileStorageUtils.getSavePath(account.name) + File.separator + name);
+        file.createNewFile();
+
+        FileWriter writer = new FileWriter(file);
+
+        for (int i = 0; i < iteration; i++) {
+            writer.write("123123123123123123123123123\n");
+        }
+        writer.flush();
+        writer.close();
+    }
+
+    private static void waitForServer(OwnCloudClient client, Uri baseUrl) {
+        GetMethod get = new GetMethod(baseUrl + "/status.php");
+
+        try {
+            int i = 0;
+            while (client.executeMethod(get) != HttpStatus.SC_OK && i < 3) {
+                System.out.println("wait…");
+                Thread.sleep(60 * 1000);
+                i++;
+            }
+
+            if (i == 3) {
+                Assert.fail("Server not ready!");
+            }
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void uploadOCUpload(OCUpload ocUpload) {
+        ConnectivityService connectivityServiceMock = new ConnectivityService() {
+            @Override
+            public boolean isInternetWalled() {
+                return false;
+            }
+
+            @Override
+            public Connectivity getConnectivity() {
+                return Connectivity.CONNECTED_WIFI;
+            }
+        };
+
+        PowerManagementService powerManagementServiceMock = new PowerManagementService() {
+            @NonNull
+            @Override
+            public BatteryStatus getBattery() {
+                return new BatteryStatus();
+            }
+
+            @Override
+            public boolean isPowerSavingEnabled() {
+                return false;
+            }
+
+            @Override
+            public boolean isPowerSavingExclusionAvailable() {
+                return false;
+            }
+        };
+
+        UserAccountManager accountManager = UserAccountManagerImpl.fromContext(targetContext);
+        UploadsStorageManager uploadsStorageManager = new UploadsStorageManager(accountManager,
+                                                                                targetContext.getContentResolver());
+
+        UploadFileOperation newUpload = new UploadFileOperation(
+            uploadsStorageManager,
+            connectivityServiceMock,
+            powerManagementServiceMock,
+            user,
+            null,
+            ocUpload,
+            FileUploader.NameCollisionPolicy.DEFAULT,
+            FileUploader.LOCAL_BEHAVIOUR_COPY,
+            targetContext,
+            false,
+            false
+        );
+        newUpload.addRenameUploadListener(() -> {
+            // dummy
+        });
+
+        newUpload.setRemoteFolderToBeCreated();
+
+        RemoteOperationResult result = newUpload.execute(client, getStorageManager());
+        assertTrue(result.getLogMessage(), result.isSuccess());
+    }
+}

+ 2 - 2
src/androidTest/java/com/owncloud/android/datamodel/FileDataStorageManagerTest.java

@@ -24,7 +24,7 @@ package com.owncloud.android.datamodel;
 
 import android.content.ContentValues;
 
-import com.owncloud.android.AbstractIT;
+import com.owncloud.android.AbstractOnServerIT;
 import com.owncloud.android.db.ProviderMeta;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.resources.files.CreateFolderRemoteOperation;
@@ -50,7 +50,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-abstract public class FileDataStorageManagerTest extends AbstractIT {
+abstract public class FileDataStorageManagerTest extends AbstractOnServerIT {
 
     protected FileDataStorageManager sut;
 

+ 6 - 0
src/androidTest/java/com/owncloud/android/ui/activity/ConflictsResolveActivityIT.java

@@ -35,6 +35,7 @@ import com.owncloud.android.lib.resources.files.UploadFileRemoteOperation;
 import com.owncloud.android.operations.RefreshFolderOperation;
 import com.owncloud.android.ui.dialog.ConflictsResolveDialog;
 import com.owncloud.android.utils.FileStorageUtils;
+import com.owncloud.android.utils.ScreenshotTest;
 
 import org.junit.Rule;
 import org.junit.Test;
@@ -59,6 +60,7 @@ public class ConflictsResolveActivityIT extends AbstractIT {
     private boolean returnCode;
 
     @Test
+    @ScreenshotTest
     public void screenshotTextFiles() {
         OCFile newFile = new OCFile("/newFile.txt");
         newFile.setFileLength(56000);
@@ -94,6 +96,7 @@ public class ConflictsResolveActivityIT extends AbstractIT {
     }
 
     @Test
+    // @ScreenshotTest // todo run without real server
     public void screenshotImages() throws IOException {
         FileDataStorageManager storageManager = new FileDataStorageManager(account,
                                                                            targetContext.getContentResolver());
@@ -187,6 +190,7 @@ public class ConflictsResolveActivityIT extends AbstractIT {
     }
 
     @Test
+    @ScreenshotTest
     public void keepExisting() {
         returnCode = false;
 
@@ -231,6 +235,7 @@ public class ConflictsResolveActivityIT extends AbstractIT {
     }
 
     @Test
+    @ScreenshotTest
     public void keepNew() {
         returnCode = false;
 
@@ -275,6 +280,7 @@ public class ConflictsResolveActivityIT extends AbstractIT {
     }
 
     @Test
+    @ScreenshotTest
     public void keepBoth() {
         returnCode = false;
 

+ 160 - 0
src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.java

@@ -0,0 +1,160 @@
+/*
+ *
+ * Nextcloud Android client application
+ *
+ * @author Tobias Kaminsky
+ * Copyright (C) 2020 Tobias Kaminsky
+ * Copyright (C) 2020 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.ui.dialog;
+
+import android.Manifest;
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.content.Intent;
+
+import com.facebook.testing.screenshot.Screenshot;
+import com.nextcloud.client.account.RegisteredUser;
+import com.nextcloud.client.account.Server;
+import com.nextcloud.ui.ChooseAccountDialogFragment;
+import com.owncloud.android.AbstractIT;
+import com.owncloud.android.MainApp;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.lib.common.OwnCloudAccount;
+import com.owncloud.android.lib.common.accounts.AccountUtils;
+import com.owncloud.android.lib.resources.status.OwnCloudVersion;
+import com.owncloud.android.ui.activity.FileDisplayActivity;
+import com.owncloud.android.utils.ScreenshotTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Objects;
+
+import androidx.fragment.app.DialogFragment;
+import androidx.test.espresso.intent.rule.IntentsTestRule;
+import androidx.test.rule.GrantPermissionRule;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+public class DialogFragmentIT extends AbstractIT {
+    @Rule public IntentsTestRule<FileDisplayActivity> activityRule =
+        new IntentsTestRule<>(FileDisplayActivity.class, true, false);
+
+    @Rule
+    public final GrantPermissionRule permissionRule = GrantPermissionRule.grant(
+        Manifest.permission.WRITE_EXTERNAL_STORAGE);
+
+    @Test
+//    @ScreenshotTest
+    public void testRenameFileDialog() {
+        RenameFileDialogFragment dialog = RenameFileDialogFragment.newInstance(new OCFile("/Test/"));
+        showDialog(dialog);
+    }
+
+    @Test
+    @ScreenshotTest
+    public void testLoadingDialog() {
+        LoadingDialog dialog = LoadingDialog.newInstance("Wait…");
+        showDialog(dialog);
+    }
+
+    @Test
+    @ScreenshotTest
+    public void testRemoveFileDialog() {
+        RemoveFilesDialogFragment dialog = RemoveFilesDialogFragment.newInstance(new OCFile("/Test.md"));
+        showDialog(dialog);
+    }
+
+    @Test
+    @ScreenshotTest
+    public void testRemoveFilesDialog() {
+        ArrayList<OCFile> toDelete = new ArrayList<>();
+        toDelete.add(new OCFile("/Test.md"));
+        toDelete.add(new OCFile("/Document.odt"));
+
+        RemoveFilesDialogFragment dialog = RemoveFilesDialogFragment.newInstance(toDelete);
+        showDialog(dialog);
+    }
+
+    @Test
+    @ScreenshotTest
+    public void testRemoveFolderDialog() {
+        RemoveFilesDialogFragment dialog = RemoveFilesDialogFragment.newInstance(new OCFile("/Folder/"));
+        showDialog(dialog);
+    }
+
+    @Test
+    @ScreenshotTest
+    public void testRemoveFoldersDialog() {
+        ArrayList<OCFile> toDelete = new ArrayList<>();
+        toDelete.add(new OCFile("/Folder/"));
+        toDelete.add(new OCFile("/Documents/"));
+
+        RemoveFilesDialogFragment dialog = RemoveFilesDialogFragment.newInstance(toDelete);
+        showDialog(dialog);
+    }
+
+    @Test
+    // @ScreenshotTest
+    public void testNewFolderDialog() {
+        CreateFolderDialogFragment sut = CreateFolderDialogFragment.newInstance(new OCFile("/"));
+        showDialog(sut);
+    }
+
+    @Test
+    @ScreenshotTest
+    public void testAccountChooserDialog() throws AccountUtils.AccountNotFoundException {
+        AccountManager accountManager = AccountManager.get(targetContext);
+        for (Account account : accountManager.getAccounts()) {
+            accountManager.removeAccountExplicitly(account);
+        }
+
+        Account newAccount = new Account("test@server.com", MainApp.getAccountType(targetContext));
+        accountManager.addAccountExplicitly(newAccount, "password", null);
+        accountManager.setUserData(newAccount, AccountUtils.Constants.KEY_OC_BASE_URL, "https://server.com");
+        accountManager.setUserData(newAccount, AccountUtils.Constants.KEY_USER_ID, "test");
+
+
+        Account newAccount2 = new Account("user1@server.com", MainApp.getAccountType(targetContext));
+        accountManager.addAccountExplicitly(newAccount2, "password", null);
+        accountManager.setUserData(newAccount2, AccountUtils.Constants.KEY_OC_BASE_URL, "https://server.com");
+        accountManager.setUserData(newAccount2, AccountUtils.Constants.KEY_USER_ID, "user1");
+        accountManager.setUserData(newAccount2, AccountUtils.Constants.KEY_OC_VERSION, "19.0.0.0");
+
+        ChooseAccountDialogFragment sut =
+            ChooseAccountDialogFragment.newInstance(new RegisteredUser(newAccount,
+                                                                       new OwnCloudAccount(newAccount, targetContext),
+                                                                       new Server(URI.create("https://server.com"),
+                                                                                  OwnCloudVersion.nextcloud_19)));
+        showDialog(sut);
+    }
+
+    private void showDialog(DialogFragment dialog) {
+        Intent intent = new Intent(targetContext, FileDisplayActivity.class);
+        FileDisplayActivity sut = activityRule.launchActivity(intent);
+
+        dialog.show(sut.getSupportFragmentManager(), "");
+
+        getInstrumentation().waitForIdleSync();
+        shortSleep();
+
+        Screenshot.snap(Objects.requireNonNull(dialog.requireDialog().getWindow()).getDecorView()).record();
+    }
+}

+ 4 - 5
src/androidTest/java/com/owncloud/android/ui/fragment/OCFileListFragmentIT.kt

@@ -49,7 +49,6 @@ import com.owncloud.android.operations.RefreshFolderOperation
 import com.owncloud.android.operations.UploadFileOperation
 import com.owncloud.android.ui.activity.FileDisplayActivity
 import com.owncloud.android.utils.FileStorageUtils
-import com.owncloud.android.utils.ScreenshotTest
 import junit.framework.TestCase
 import org.junit.Assert.assertTrue
 import org.junit.Rule
@@ -89,7 +88,7 @@ class OCFileListFragmentIT : AbstractIT() {
     }
 
     @Test
-    @ScreenshotTest
+    // @ScreenshotTest // todo run without real server
     fun showRichWorkspace() {
         assertTrue(CreateFolderOperation("/test/", user, targetContext).execute(client, storageManager).isSuccess)
 
@@ -176,7 +175,7 @@ class OCFileListFragmentIT : AbstractIT() {
     }
 
     @Test
-    @ScreenshotTest
+    // @ScreenshotTest // todo run without real server
     fun createAndShowShareToUser() {
         val path = "/shareToAdmin/"
         TestCase.assertTrue(
@@ -207,7 +206,7 @@ class OCFileListFragmentIT : AbstractIT() {
     }
 
     @Test
-    @ScreenshotTest
+    // @ScreenshotTest // todo run without real server
     fun createAndShowShareToGroup() {
         val path = "/shareToGroup/"
         TestCase.assertTrue(
@@ -271,7 +270,7 @@ class OCFileListFragmentIT : AbstractIT() {
 //    }
 
     @Test
-    @ScreenshotTest
+    // @ScreenshotTest // todo run without real server
     fun createAndShowShareViaLink() {
         val path = "/shareViaLink/"
         TestCase.assertTrue(

+ 2 - 3
src/androidTest/java/com/owncloud/android/ui/preview/PreviewTextFileFragmentTest.java

@@ -30,7 +30,6 @@ import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.MimeTypeUtil;
-import com.owncloud.android.utils.ScreenshotTest;
 
 import org.junit.Rule;
 import org.junit.Test;
@@ -51,7 +50,7 @@ public class PreviewTextFileFragmentTest extends AbstractIT {
         Manifest.permission.WRITE_EXTERNAL_STORAGE);
 
     @Test
-    @ScreenshotTest
+    // @ScreenshotTest // todo run without real server
     public void displaySimpleTextFile() {
         FileDisplayActivity sut = activityRule.launchActivity(null);
 
@@ -69,7 +68,7 @@ public class PreviewTextFileFragmentTest extends AbstractIT {
     }
 
     @Test
-    @ScreenshotTest
+    // @ScreenshotTest // todo run without real server
     public void displayJavaSnippetFile() throws IOException {
         FileDisplayActivity sut = activityRule.launchActivity(null);
 

+ 3 - 1
src/main/java/com/nextcloud/ui/ChooseAccountDialogFragment.kt

@@ -153,7 +153,9 @@ class ChooseAccountDialogFragment : DialogFragment(), AvatarGenerationListener,
     }
 
     override fun avatarGenerated(avatarDrawable: Drawable?, callContext: Any?) {
-        user_icon.setImageDrawable(avatarDrawable)
+        if (user_icon != null) {
+            user_icon.setImageDrawable(avatarDrawable)
+        }
     }
 
     override fun onAccountClicked(user: User?) {

+ 5 - 1
src/main/java/com/owncloud/android/ui/adapter/UserListAdapter.java

@@ -269,7 +269,11 @@ public class UserListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
             try {
                 View viewItem = binding.userIcon;
                 viewItem.setTag(user.getAccountName());
-                DisplayUtils.setAvatar(user, avatarGenerationListener, accountAvatarRadiusDimension, context.getResources(), viewItem,
+                DisplayUtils.setAvatar(user,
+                                       avatarGenerationListener,
+                                       accountAvatarRadiusDimension,
+                                       context.getResources(),
+                                       viewItem,
                                        context);
             } catch (Exception e) {
                 Log_OC.e(TAG, "Error calculating RGB value for account list item.", e);

+ 1 - 1
src/main/res/layout/account_item.xml

@@ -52,7 +52,7 @@
                 android:layout_marginEnd="@dimen/account_item_layout_user_image_margin"
                 android:layout_marginBottom="@dimen/account_item_layout_user_image_margin"
                 android:contentDescription="@string/avatar"
-                android:src="@drawable/folder" />
+                android:src="@drawable/ic_user" />
 
             <ImageView
                 android:id="@+id/ticker"