Remove unmaintained UI tests and remove deprecated AndroidJunit4 usage
This commit is contained in:
parent
0ff8ac3cb5
commit
c68e30e142
@ -100,6 +100,7 @@ ext {
|
||||
rulesVersion = '1.4.0'
|
||||
contributionVersion = '3.4.0'
|
||||
uiautomatorVersion = '2.2.0'
|
||||
androidxTestJunitKtlnVersion = '1.1.3'
|
||||
|
||||
androidxCoreVersion = '1.6.0'
|
||||
androidxFragmentVersion = '1.3.6'
|
||||
@ -126,6 +127,7 @@ ext {
|
||||
documentFile : "androidx.documentfile:documentfile:${androidxDocumentfileVersion}",
|
||||
recyclerView : "androidx.recyclerview:recyclerview:${androidxRecyclerViewVersion}",
|
||||
androidxTestCore : "androidx.test:core:${androidxTestCoreVersion}",
|
||||
androidxTestJunitKtln : "androidx.test.ext:junit-ktx:${androidxTestJunitKtlnVersion}",
|
||||
commonsCodec : "commons-codec:commons-codec:${commonsCodecVersion}",
|
||||
cryptolib : "org.cryptomator:cryptolib:${cryptolibVersion}",
|
||||
dagger : "com.google.dagger:dagger:${daggerVersion}",
|
||||
|
@ -191,6 +191,7 @@ dependencies {
|
||||
testRuntimeOnly dependencies.junitEngine
|
||||
testImplementation dependencies.junitParams
|
||||
testRuntimeOnly dependencies.junit4Engine
|
||||
implementation dependencies.androidxTestJunitKtln
|
||||
|
||||
testImplementation dependencies.mockito
|
||||
testImplementation dependencies.mockitoKotlin
|
||||
|
@ -2,9 +2,10 @@ package org.cryptomator.data.db
|
||||
|
||||
import android.content.Context
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import androidx.test.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import androidx.test.runner.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.google.common.base.Optional
|
||||
import org.cryptomator.data.db.entities.CloudEntityDao
|
||||
import org.cryptomator.data.db.entities.UpdateCheckEntityDao
|
||||
import org.cryptomator.data.db.entities.VaultEntityDao
|
||||
@ -25,7 +26,7 @@ import org.junit.runner.RunWith
|
||||
@SmallTest
|
||||
class UpgradeDatabaseTest {
|
||||
|
||||
private val context = InstrumentationRegistry.getTargetContext()
|
||||
private val context = InstrumentationRegistry.getInstrumentation().context
|
||||
private val sharedPreferencesHandler = SharedPreferencesHandler(context)
|
||||
private lateinit var db: Database
|
||||
|
||||
|
@ -1,422 +0,0 @@
|
||||
package org.cryptomator.presentation;
|
||||
|
||||
import androidx.test.rule.ActivityTestRule;
|
||||
|
||||
import org.cryptomator.data.cloud.local.file.RootLocalFolder;
|
||||
import org.cryptomator.domain.Cloud;
|
||||
import org.cryptomator.domain.CloudFile;
|
||||
import org.cryptomator.domain.CloudFolder;
|
||||
import org.cryptomator.domain.CloudNode;
|
||||
import org.cryptomator.domain.CloudType;
|
||||
import org.cryptomator.domain.LocalStorageCloud;
|
||||
import org.cryptomator.domain.exception.BackendException;
|
||||
import org.cryptomator.domain.exception.CloudNodeAlreadyExistsException;
|
||||
import org.cryptomator.domain.repository.CloudContentRepository;
|
||||
import org.cryptomator.domain.usecases.ProgressAware;
|
||||
import org.cryptomator.domain.usecases.cloud.ByteArrayDataSource;
|
||||
import org.cryptomator.presentation.di.component.ApplicationComponent;
|
||||
import org.cryptomator.presentation.testCloud.CryptoTestCloud;
|
||||
import org.cryptomator.presentation.testCloud.DropboxTestCloud;
|
||||
import org.cryptomator.presentation.testCloud.GoogledriveTestCloud;
|
||||
import org.cryptomator.presentation.testCloud.LocalStorageTestCloud;
|
||||
import org.cryptomator.presentation.testCloud.LocalTestCloud;
|
||||
import org.cryptomator.presentation.testCloud.OnedriveTestCloud;
|
||||
import org.cryptomator.presentation.testCloud.TestCloud;
|
||||
import org.cryptomator.presentation.testCloud.WebdavTestCloud;
|
||||
import org.cryptomator.presentation.ui.activity.SplashActivity;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static androidx.test.InstrumentationRegistry.getTargetContext;
|
||||
import static org.cryptomator.presentation.CloudNodeMatchers.aFile;
|
||||
import static org.cryptomator.presentation.CloudNodeMatchers.folder;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.collection.IsEmptyCollection.emptyCollectionOf;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class CloudContentRepositoryBlackboxTest {
|
||||
|
||||
private static final byte[] DIGITS_ONE_TO_TEN_AS_BYTES = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
private static final byte[] DIGITS_SEVEN_TO_ONE_AS_BYTES = new byte[] {7, 6, 5, 4, 3, 2, 1};
|
||||
|
||||
private static Cloud cloud;
|
||||
private static TestCloud inTestCloud;
|
||||
private static boolean setupCloudCompleted = false;
|
||||
@Rule
|
||||
public final ActivityTestRule<SplashActivity> activityTestRule = new ActivityTestRule<>(SplashActivity.class);
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
private CloudContentRepository inTest;
|
||||
private CloudFolder root;
|
||||
|
||||
public CloudContentRepositoryBlackboxTest(TestCloud testCloud) {
|
||||
if (inTestCloud != null && inTestCloud != testCloud) {
|
||||
setupCloudCompleted = false;
|
||||
}
|
||||
|
||||
inTestCloud = testCloud;
|
||||
}
|
||||
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
public static TestCloud[] data() {
|
||||
return new TestCloud[] { //
|
||||
new LocalStorageTestCloud(), //
|
||||
new LocalTestCloud(), //
|
||||
new WebdavTestCloud(getTargetContext()), //
|
||||
new DropboxTestCloud(getTargetContext()), //
|
||||
new GoogledriveTestCloud(), //
|
||||
new OnedriveTestCloud(getTargetContext()), //
|
||||
new CryptoTestCloud()};
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws BackendException {
|
||||
|
||||
ApplicationComponent appComponent = ((CryptomatorApp) activityTestRule //
|
||||
.getActivity() //
|
||||
.getApplication()) //
|
||||
.getComponent();
|
||||
|
||||
if (!setupCloudCompleted) {
|
||||
if (inTestCloud instanceof CryptoTestCloud) {
|
||||
// FIXME 343 @julian just for testcase local cloud
|
||||
Cloud testCloud = appComponent.cloudRepository().clouds(CloudType.LOCAL).get(0);
|
||||
CloudFolder rootFolder = new RootLocalFolder((LocalStorageCloud) testCloud);
|
||||
cloud = ((CryptoTestCloud) inTestCloud).getInstance(appComponent, testCloud, rootFolder);
|
||||
} else {
|
||||
cloud = inTestCloud.getInstance(appComponent);
|
||||
}
|
||||
|
||||
setupCloudCompleted = true;
|
||||
}
|
||||
|
||||
inTest = appComponent.cloudContentRepository();
|
||||
root = inTest.create(inTest.resolve(cloud, UUID.randomUUID().toString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListEmptyDirectory() throws BackendException {
|
||||
assertThat(listingOf(root), is(emptyCollectionOf(CloudNode.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListDirectory() throws BackendException {
|
||||
createParentsAndWrite("a", DIGITS_SEVEN_TO_ONE_AS_BYTES);
|
||||
createParentsAndWrite("b.dat", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
createParentsAndWrite("empty.txt", new byte[0]);
|
||||
inTest.create(inTest.folder(root, "b"));
|
||||
inTest.create(inTest.folder(root, "c"));
|
||||
|
||||
assertThat(listingOf(root), containsInAnyOrder( //
|
||||
aFile().withName("a").withSize(DIGITS_SEVEN_TO_ONE_AS_BYTES.length), //
|
||||
aFile().withName("b.dat").withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length), //
|
||||
aFile().withName("empty.txt").withSize(0L), //
|
||||
folder("b"), //
|
||||
folder("c")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDirectory() throws BackendException {
|
||||
CloudFolder created = inTest.folder(root, "created");
|
||||
created = inTest.create(created);
|
||||
|
||||
assertThat(listingOf(created), is(emptyCollectionOf(CloudNode.class)));
|
||||
assertThat(listingOf(root), containsInAnyOrder(folder("created")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDirectory() throws BackendException {
|
||||
inTest.create(inTest.folder(root, "created"));
|
||||
inTest.delete(inTest.folder(root, "created"));
|
||||
|
||||
assertThat(inTest.exists(inTest.folder(root, "created")), is(false));
|
||||
assertThat(listingOf(root), is(emptyCollectionOf(CloudNode.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testUploadFile() throws BackendException {
|
||||
Date start = new Date();
|
||||
CloudFile file = createParentsAndWrite("file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
|
||||
assertThat(file, is(aFile() //
|
||||
.withName("file") //
|
||||
.withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length) //
|
||||
.withModifiedIn(start, new Date())));
|
||||
assertThat(listingOf(root), //
|
||||
containsInAnyOrder(aFile() //
|
||||
.withName("file") //
|
||||
.withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testReplaceFile() throws BackendException {
|
||||
createParentsAndWrite("file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
Date start = new Date();
|
||||
CloudFile file = createParentsAndWriteOrReplace("file", DIGITS_SEVEN_TO_ONE_AS_BYTES);
|
||||
|
||||
assertThat(file, is(aFile() //
|
||||
.withName("file") //
|
||||
.withSize(DIGITS_SEVEN_TO_ONE_AS_BYTES.length) //
|
||||
.withModifiedIn(start, new Date())));
|
||||
assertThat(listingOf(root), //
|
||||
containsInAnyOrder(aFile() //
|
||||
.withName("file") //
|
||||
.withSize(DIGITS_SEVEN_TO_ONE_AS_BYTES.length)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUploadExistingFileWithoutReplaceFlag() throws BackendException {
|
||||
createParentsAndWrite("file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
|
||||
thrown.expect(CloudNodeAlreadyExistsException.class);
|
||||
thrown.expectMessage("CloudNode already exists and replace is false");
|
||||
|
||||
createParentsAndWrite("file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDownloadFile() throws BackendException {
|
||||
createParentsAndWrite("file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
|
||||
assertThat(read(inTest.file(root, "file")), is(DIGITS_ONE_TO_TEN_AS_BYTES));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteFile() throws BackendException {
|
||||
createParentsAndWrite("file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
inTest.delete(inTest.file(root, "file"));
|
||||
|
||||
assertThat(inTest.exists(inTest.file(root, "file")), is(false));
|
||||
assertThat(listingOf(root), is(emptyCollectionOf(CloudNode.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testRenameDirectory() throws BackendException {
|
||||
CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
CloudFolder directory = file.getParent();
|
||||
CloudFolder target = inTest.folder(root, "newName");
|
||||
|
||||
target = inTest.move(directory, target);
|
||||
|
||||
assertThat(listingOf(target), containsInAnyOrder(aFile() //
|
||||
.withName("file") //
|
||||
.withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenameDirectoryToExistingDirectory() throws BackendException {
|
||||
CloudFolder directory = inTest.folder(root, "directory");
|
||||
directory = inTest.create(directory);
|
||||
CloudFolder target = inTest.folder(root, "newName");
|
||||
target = inTest.create(target);
|
||||
|
||||
thrown.expect(CloudNodeAlreadyExistsException.class);
|
||||
thrown.expectMessage("newName");
|
||||
|
||||
inTest.move(directory, target);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testRenameDirectoryToExistingFile() throws BackendException {
|
||||
CloudFolder directory = inTest.folder(root, "directory");
|
||||
directory = inTest.create(directory);
|
||||
CloudFolder target = inTest.folder(root, "newName");
|
||||
createParentsAndWrite("newName", new byte[0]);
|
||||
|
||||
thrown.expect(CloudNodeAlreadyExistsException.class);
|
||||
thrown.expectMessage("newName");
|
||||
|
||||
inTest.move(directory, target);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testMoveDirectory() throws BackendException {
|
||||
CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
CloudFolder directory = file.getParent();
|
||||
CloudFolder newParent = inTest.create(inTest.folder(root, "newParent"));
|
||||
CloudFolder target = inTest.folder(newParent, "directory");
|
||||
|
||||
target = inTest.move(directory, target);
|
||||
|
||||
assertThat(listingOf(target), containsInAnyOrder(aFile() //
|
||||
.withName("file") //
|
||||
.withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testMoveDirectoryToExistingDirectory() throws BackendException {
|
||||
CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
CloudFolder directory = file.getParent();
|
||||
CloudFolder newParent = inTest.create(inTest.folder(root, "newParent"));
|
||||
CloudFolder target = inTest.folder(newParent, "directory");
|
||||
target = inTest.create(target);
|
||||
|
||||
thrown.expect(CloudNodeAlreadyExistsException.class);
|
||||
thrown.expectMessage("directory");
|
||||
|
||||
inTest.move(directory, target);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testMoveDirectoryToExistingFile() throws BackendException {
|
||||
CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
CloudFolder directory = file.getParent();
|
||||
CloudFolder newParent = inTest.create(inTest.folder(root, "newParent"));
|
||||
CloudFolder target = inTest.folder(newParent, "directory");
|
||||
createParentsAndWrite("newParent/directory", new byte[0]);
|
||||
|
||||
thrown.expect(CloudNodeAlreadyExistsException.class);
|
||||
thrown.expectMessage("directory");
|
||||
|
||||
inTest.move(directory, target);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testMoveAndRenameDirectory() throws BackendException {
|
||||
CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
CloudFolder directory = file.getParent();
|
||||
CloudFolder newParent = inTest.create(inTest.folder(root, "newParent"));
|
||||
CloudFolder target = inTest.folder(newParent, "newName");
|
||||
|
||||
target = inTest.move(directory, target);
|
||||
|
||||
assertThat(listingOf(target), containsInAnyOrder(aFile() //
|
||||
.withName("file") //
|
||||
.withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testMoveAndRenameDirectoryToExistingDirectory() throws BackendException {
|
||||
CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
CloudFolder directory = file.getParent();
|
||||
CloudFolder newParent = inTest.create(inTest.folder(root, "newParent"));
|
||||
CloudFolder target = inTest.folder(newParent, "newName");
|
||||
target = inTest.create(target);
|
||||
|
||||
thrown.expect(CloudNodeAlreadyExistsException.class);
|
||||
thrown.expectMessage("newName");
|
||||
|
||||
inTest.move(directory, target);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testMoveAndRenameDirectoryToExistingFile() throws BackendException {
|
||||
CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
CloudFolder directory = file.getParent();
|
||||
CloudFolder newParent = inTest.create(inTest.folder(root, "newParent"));
|
||||
CloudFolder target = inTest.folder(newParent, "newName");
|
||||
createParentsAndWrite("newParent/newName", new byte[0]);
|
||||
|
||||
thrown.expect(CloudNodeAlreadyExistsException.class);
|
||||
thrown.expectMessage("newName");
|
||||
|
||||
inTest.move(directory, target);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testRenameFile() throws BackendException {
|
||||
CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
CloudFile target = inTest.file(file.getParent(), "newName");
|
||||
|
||||
target = inTest.move(file, target);
|
||||
|
||||
assertThat(listingOf(file.getParent()), containsInAnyOrder(aFile() //
|
||||
.withName("newName") //
|
||||
.withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length)));
|
||||
assertThat(read(target), is(DIGITS_ONE_TO_TEN_AS_BYTES));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testMoveFile() throws BackendException {
|
||||
CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
CloudFolder oldParent = file.getParent();
|
||||
CloudFolder newParent = inTest.create(inTest.folder(root, "newParent"));
|
||||
CloudFile target = inTest.file(newParent, "file");
|
||||
|
||||
target = inTest.move(file, target);
|
||||
|
||||
assertThat(listingOf(oldParent), is(emptyCollectionOf(CloudNode.class)));
|
||||
assertThat(listingOf(newParent), containsInAnyOrder(aFile() //
|
||||
.withName("file") //
|
||||
.withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length)));
|
||||
assertThat(read(target), is(DIGITS_ONE_TO_TEN_AS_BYTES));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testMoveAndRenameFile() throws BackendException {
|
||||
CloudFile file = createParentsAndWrite("directory/file", DIGITS_ONE_TO_TEN_AS_BYTES);
|
||||
CloudFolder oldParent = file.getParent();
|
||||
CloudFolder newParent = inTest.create(inTest.folder(root, "newParent"));
|
||||
CloudFile target = inTest.file(newParent, "newName");
|
||||
|
||||
target = inTest.move(file, target);
|
||||
|
||||
assertThat(listingOf(oldParent), is(emptyCollectionOf(CloudNode.class)));
|
||||
assertThat(listingOf(newParent), containsInAnyOrder(aFile() //
|
||||
.withName("newName") //
|
||||
.withSize(DIGITS_ONE_TO_TEN_AS_BYTES.length)));
|
||||
assertThat(read(target), is(DIGITS_ONE_TO_TEN_AS_BYTES));
|
||||
}
|
||||
|
||||
@After
|
||||
public void teardown() throws BackendException {
|
||||
if (inTest != null && root != null) {
|
||||
inTest.delete(root);
|
||||
}
|
||||
}
|
||||
|
||||
private List<CloudNode> listingOf(CloudFolder testRoot) throws BackendException {
|
||||
return inTest.list(testRoot);
|
||||
}
|
||||
|
||||
private byte[] read(CloudFile file) throws BackendException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
inTest.read(file, null, out, ProgressAware.NO_OP_PROGRESS_AWARE_DOWNLOAD);
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
private CloudFile createParentsAndWrite(String path, byte[] data) throws BackendException {
|
||||
return createParentsAndWriteOrReplaceImpl(path, data, false);
|
||||
}
|
||||
|
||||
private CloudFile createParentsAndWriteOrReplace(String path, byte[] data) throws BackendException {
|
||||
return createParentsAndWriteOrReplaceImpl(path, data, true);
|
||||
}
|
||||
|
||||
private CloudFile createParentsAndWriteOrReplaceImpl(String path, byte[] data, boolean repalce) throws BackendException {
|
||||
path = root.getName() + "/" + path;
|
||||
String pathToParent = path.substring(0, path.lastIndexOf('/') + 1);
|
||||
String name = path.substring(path.lastIndexOf('/') + 1);
|
||||
CloudFolder parent = inTest.resolve(cloud, pathToParent);
|
||||
if (!inTest.exists(parent)) {
|
||||
parent = inTest.create(parent);
|
||||
}
|
||||
CloudFile file = inTest.file(parent, name, new Long(data.length));
|
||||
return inTest.write(file, ByteArrayDataSource.from(data), ProgressAware.NO_OP_PROGRESS_AWARE_UPLOAD, repalce, data.length);
|
||||
}
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
package org.cryptomator.presentation;
|
||||
|
||||
import org.cryptomator.domain.CloudFile;
|
||||
import org.cryptomator.domain.CloudFolder;
|
||||
import org.cryptomator.domain.CloudNode;
|
||||
import com.google.common.base.Optional;
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.TypeSafeDiagnosingMatcher;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
class CloudNodeMatchers {
|
||||
|
||||
public static Matcher<CloudNode> aFile(final String name) {
|
||||
return (Matcher) new TypeSafeDiagnosingMatcher<CloudFile>() {
|
||||
@Override
|
||||
protected boolean matchesSafely(CloudFile file, Description description) {
|
||||
if (name.equals(file.getName())) {
|
||||
return true;
|
||||
} else {
|
||||
description.appendText("aFile with name '").appendText(file.getName()).appendText("'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("aFile with name '").appendText(name).appendText("'");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static FileMatcher aFile() {
|
||||
return new FileMatcher();
|
||||
}
|
||||
|
||||
public static Matcher<CloudNode> folder(final String name) {
|
||||
return (Matcher) new TypeSafeDiagnosingMatcher<CloudFolder>() {
|
||||
@Override
|
||||
protected boolean matchesSafely(CloudFolder file, org.hamcrest.Description description) {
|
||||
if (name.equals(file.getName())) {
|
||||
return true;
|
||||
} else {
|
||||
description.appendText("folder with name '").appendText(file.getName()).appendText("'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTo(org.hamcrest.Description description) {
|
||||
description.appendText("folder with name '").appendText(name).appendText("'");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static class FileMatcher extends TypeSafeDiagnosingMatcher<CloudNode> {
|
||||
|
||||
private String nameToCheck;
|
||||
private Optional<Long> sizeToCheck;
|
||||
|
||||
private Date minModifiedToCheck;
|
||||
private Date maxModifiedToCheck;
|
||||
|
||||
private FileMatcher() {
|
||||
super(CloudFile.class);
|
||||
}
|
||||
|
||||
public FileMatcher withName(String name) {
|
||||
this.nameToCheck = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FileMatcher withSize(int size) {
|
||||
return withSize(Long.valueOf(size));
|
||||
}
|
||||
|
||||
public FileMatcher withSize(Long size) {
|
||||
this.sizeToCheck = Optional.ofNullable(size);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FileMatcher withModifiedIn(Date minModified, Date maxModified) {
|
||||
this.minModifiedToCheck = minModified;
|
||||
this.maxModifiedToCheck = maxModified;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("a file");
|
||||
if (nameToCheck != null) {
|
||||
description.appendText(" with name ").appendText(nameToCheck);
|
||||
}
|
||||
if (sizeToCheck != null) {
|
||||
description.appendText(" with size ").appendValue(sizeToCheck);
|
||||
}
|
||||
if (minModifiedToCheck != null) {
|
||||
description.appendText(" with modified in [").appendValue(minModifiedToCheck).appendText(",").appendValue(maxModifiedToCheck).appendText("]");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(CloudNode cloudNode, Description description) {
|
||||
CloudFile cloudFile = (CloudFile) cloudNode;
|
||||
boolean match = true;
|
||||
description.appendText("a file");
|
||||
if (nameToCheck != null && !nameToCheck.equals(cloudFile.getName())) {
|
||||
description.appendText(" with name ").appendText(cloudFile.getName());
|
||||
match = false;
|
||||
}
|
||||
if (sizeToCheck != null && !sizeToCheck.equals(cloudFile.getSize())) {
|
||||
description.appendText(" with size ").appendValue(cloudFile.getSize());
|
||||
match = false;
|
||||
}
|
||||
if (minModifiedToCheck != null && dateInRange(minModifiedToCheck, maxModifiedToCheck, cloudFile.getModified())) {
|
||||
description.appendText(" with modified ").appendValue(cloudFile.getModified());
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
private boolean dateInRange(Date min, Date max, Optional<Date> modified) {
|
||||
return modified.isPresent() && !modified.get().before(min) && !modified.get().after(max);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
package org.cryptomator.presentation.testCloud;
|
||||
|
||||
import org.cryptomator.domain.Cloud;
|
||||
import org.cryptomator.domain.CloudFolder;
|
||||
import org.cryptomator.domain.Vault;
|
||||
import org.cryptomator.domain.exception.BackendException;
|
||||
import org.cryptomator.domain.exception.FatalBackendException;
|
||||
import org.cryptomator.presentation.di.component.ApplicationComponent;
|
||||
|
||||
import static org.cryptomator.domain.Vault.aVault;
|
||||
|
||||
public class CryptoTestCloud extends TestCloud {
|
||||
|
||||
private final static String VAULT_PASSWORD = "password";
|
||||
private final static String VAULT_NAME = "testVault";
|
||||
|
||||
@Override
|
||||
public Cloud getInstance(ApplicationComponent appComponent) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public Cloud getInstance(ApplicationComponent appComponent, Cloud testCloud, CloudFolder rootFolder) {
|
||||
try {
|
||||
CloudFolder vaultFolder = appComponent //
|
||||
.cloudContentRepository() //
|
||||
.folder(rootFolder, VAULT_NAME);
|
||||
|
||||
Vault vault = aVault() //
|
||||
.thatIsNew() //
|
||||
.withCloud(testCloud) //
|
||||
.withNamePathAndCloudFrom(vaultFolder) //
|
||||
.build();
|
||||
|
||||
cleanup(appComponent, vault, vaultFolder);
|
||||
|
||||
vaultFolder = appComponent.cloudContentRepository().create(vaultFolder);
|
||||
appComponent.cloudRepository().create(vaultFolder, VAULT_PASSWORD);
|
||||
vault = appComponent.vaultRepository().store(vault);
|
||||
|
||||
return appComponent.cloudRepository().unlock(vault, VAULT_PASSWORD, () -> false);
|
||||
} catch (BackendException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanup(ApplicationComponent appComponent, Vault vault, CloudFolder vaultFolder) {
|
||||
try {
|
||||
appComponent.cloudContentRepository().delete(vaultFolder);
|
||||
} catch (BackendException | FatalBackendException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
appComponent.vaultRepository().vaults().forEach(vaultInRepo -> {
|
||||
if (vaultInRepo.getName().equals(vault.getName()) //
|
||||
&& vaultInRepo.getPath().equals(vault.getPath())) {
|
||||
try {
|
||||
appComponent.vaultRepository().delete(vaultInRepo);
|
||||
} catch (BackendException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (FatalBackendException | BackendException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CryptoTestCloud";
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package org.cryptomator.presentation.testCloud;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.cryptomator.domain.Cloud;
|
||||
import org.cryptomator.domain.WebDavCloud;
|
||||
import org.cryptomator.presentation.di.component.ApplicationComponent;
|
||||
import org.cryptomator.util.crypto.CredentialCryptor;
|
||||
|
||||
public class DropboxTestCloud extends TestCloud {
|
||||
|
||||
private final Context context;
|
||||
|
||||
public DropboxTestCloud(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cloud getInstance(ApplicationComponent appComponent) {
|
||||
return WebDavCloud.aWebDavCloudCloud() //
|
||||
.withUrl("https://webdav.mc.gmx.net") //
|
||||
.withUsername("jraufelder@gmx.de") //
|
||||
.withPassword(CredentialCryptor.getInstance(context).encrypt("mG7!3B3Mx")) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DropboxTestCloud";
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
package org.cryptomator.presentation.testCloud;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.uiautomator.UiDevice;
|
||||
import androidx.test.uiautomator.UiObjectNotFoundException;
|
||||
import androidx.test.uiautomator.UiSelector;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import org.cryptomator.domain.Cloud;
|
||||
import org.cryptomator.domain.GoogleDriveCloud;
|
||||
import org.cryptomator.presentation.R;
|
||||
import org.cryptomator.presentation.di.component.ApplicationComponent;
|
||||
|
||||
import static androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.action.ViewActions.click;
|
||||
import static androidx.test.espresso.assertion.ViewAssertions.matches;
|
||||
import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withId;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withText;
|
||||
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.GOOGLE_DRIVE;
|
||||
import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.withRecyclerView;
|
||||
import static org.cryptomator.presentation.ui.activity.CloudsOperationsTest.checkLoginResult;
|
||||
import static org.cryptomator.presentation.ui.activity.CloudsOperationsTest.openCloudServices;
|
||||
|
||||
public class GoogledriveTestCloud extends TestCloud {
|
||||
|
||||
@Override
|
||||
public Cloud getInstance(ApplicationComponent appComponent) {
|
||||
login();
|
||||
return GoogleDriveCloud.aGoogleDriveCloud() //
|
||||
.withUsername("geselthyn@googlemail.com") //
|
||||
.withAccessToken("geselthyn@googlemail.com") //
|
||||
.build();
|
||||
}
|
||||
|
||||
public void login() {
|
||||
UiDevice device = UiDevice.getInstance(getInstrumentation());
|
||||
|
||||
openCloudServices(device);
|
||||
|
||||
if (alreadyLoggedIn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(GOOGLE_DRIVE, click()));
|
||||
|
||||
try {
|
||||
device //
|
||||
.findObject(new UiSelector().resourceId("android:id/text1")) //
|
||||
.click();
|
||||
|
||||
device //
|
||||
.findObject(new UiSelector().resourceId("android:id/button1")) //
|
||||
.click();
|
||||
} catch (UiObjectNotFoundException e) {
|
||||
throw new AssertionError("GoogleDrive login failed");
|
||||
}
|
||||
|
||||
device.waitForIdle();
|
||||
|
||||
checkLoginResult("Google Drive", GOOGLE_DRIVE);
|
||||
}
|
||||
|
||||
private boolean alreadyLoggedIn() {
|
||||
try {
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(GOOGLE_DRIVE, R.id.tv_cloud_name)) //
|
||||
.check(matches(withText(InstrumentationRegistry //
|
||||
.getTargetContext() //
|
||||
.getString(R.string.screen_cloud_settings_sign_out_from_cloud) + " Google Drive")));
|
||||
} catch (AssertionFailedError e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GoogledriveTestCloud";
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package org.cryptomator.presentation.testCloud;
|
||||
|
||||
import androidx.test.uiautomator.UiDevice;
|
||||
|
||||
import org.cryptomator.domain.Cloud;
|
||||
import org.cryptomator.domain.CloudType;
|
||||
import org.cryptomator.domain.LocalStorageCloud;
|
||||
import org.cryptomator.domain.exception.BackendException;
|
||||
import org.cryptomator.presentation.R;
|
||||
import org.cryptomator.presentation.di.component.ApplicationComponent;
|
||||
|
||||
import static androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.action.ViewActions.click;
|
||||
import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withId;
|
||||
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||
import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.LOCAL;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.chooseSdCard;
|
||||
import static org.cryptomator.presentation.ui.activity.CloudsOperationsTest.openCloudServices;
|
||||
import static org.cryptomator.presentation.ui.activity.LoginLocalClouds.chooseFolder;
|
||||
|
||||
public class LocalStorageTestCloud extends TestCloud {
|
||||
|
||||
@Override
|
||||
public Cloud getInstance(ApplicationComponent appComponent) {
|
||||
login();
|
||||
try {
|
||||
return appComponent.cloudRepository() //
|
||||
.clouds(CloudType.LOCAL).stream() //
|
||||
.map(LocalStorageCloud.class::cast) //
|
||||
.filter(cloud -> cloud.rootUri() != null) //
|
||||
.findFirst() //
|
||||
.get();
|
||||
} catch (BackendException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void login() {
|
||||
UiDevice device = UiDevice.getInstance(getInstrumentation());
|
||||
|
||||
openCloudServices(device);
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(LOCAL, click()));
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.floating_action_button)) //
|
||||
.perform(click());
|
||||
awaitCompleted();
|
||||
|
||||
chooseSdCard(device);
|
||||
awaitCompleted();
|
||||
|
||||
chooseFolder(device);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LocalStorageTestCloud";
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package org.cryptomator.presentation.testCloud;
|
||||
|
||||
import org.cryptomator.domain.Cloud;
|
||||
import org.cryptomator.domain.LocalStorageCloud;
|
||||
import org.cryptomator.presentation.di.component.ApplicationComponent;
|
||||
|
||||
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||
|
||||
public class LocalTestCloud extends TestCloud {
|
||||
|
||||
@Override
|
||||
public Cloud getInstance(ApplicationComponent appComponent) {
|
||||
getInstrumentation() //
|
||||
.getUiAutomation() //
|
||||
.executeShellCommand("pm grant " + "org.cryptomator" + " android.permission.READ_EXTERNAL_STORAGE");
|
||||
|
||||
getInstrumentation() //
|
||||
.getUiAutomation() //
|
||||
.executeShellCommand("pm grant " + "org.cryptomator" + " android.permission.WRITE_EXTERNAL_STORAGE");
|
||||
|
||||
return LocalStorageCloud.aLocalStorage().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LocalTestCloud";
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package org.cryptomator.presentation.testCloud;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import org.cryptomator.domain.Cloud;
|
||||
import org.cryptomator.domain.OnedriveCloud;
|
||||
import org.cryptomator.presentation.di.component.ApplicationComponent;
|
||||
|
||||
public class OnedriveTestCloud extends TestCloud {
|
||||
|
||||
private final Context context;
|
||||
|
||||
public OnedriveTestCloud(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cloud getInstance(ApplicationComponent appComponent) {
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences("com.microsoft.live", 0);
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putString("refresh_token", "OAQABAAAAAABHh4kmS_aKT5XrjzxRAtHzMkxzFfIzutF8Q04IwuU77Vmp5-ErO6muS0-watCiLjvPG" + //
|
||||
"-QICK6PwzSsJZApKZPIyTgDxJuElkhM9j9Caa-NGXKx3JPZx4Tk5X3zhmSWebZdQu2TM1N" + //
|
||||
"RrKWLl2k2m3Zj7xr1zEsjcr4tUjjrZl_W6EIglAIoi-DPOwznIEDWAzWCJeUY76CIpywax" + //
|
||||
"RTsbcZXD3u2321kIGaL-bnGLa_z5IzUbal0PcYfPNYPXXTuv8eMyl4L9Tls1tSEseTHgCu" + //
|
||||
"X3OZU2owiGQk6ycDAeyrbRaPoUOA78GYuaJGUXRmhAeH1WBccUzABdrZmAY1dAt4yu2eV7" + //
|
||||
"70RzrDQhbLCPV3u3x-7xEtvsM8w0W7096VBuu2-MXvaWuDccnCHo_PK8ketpow19_llBI9" + //
|
||||
"fx7yBnIU-HCkKuvOCKcvVq3Bv9r312bwAoWHdOrxsKrNK8aLoR317O9Cxjpr7q-YI3NSJJ" + //
|
||||
"veTK_vn2uE0e6gppGOYSmpJIvoW82ZVngpptW0jsp6rOsnkSg2yfKKpIPN-n0U1njVlYf8" + //
|
||||
"cwsS99tx8NDdCPS6MTkVmcdKRJ4dhMuuWdEm4E_hZRnnj2Pya3APxjL2eqyAR1-54TDLF-" + //
|
||||
"-L-jIJUS4bVpC_RBQn4fxcrX4s-ddo6I0ejfdC07mU_Np9p66VJ_3_Yokt64fFw-zzaGpn" + //
|
||||
"QEzRMxtJp5G40MAelYwxLhDIc-syw91JEoSSqfGJYHETKExPlnQOw-rqLGPFbIF6OKFNqO" + //
|
||||
"XtVLWKZFxIEf-EFQbhq5igZz8DZ2n-cRxC3HWi_x18tVSAA");
|
||||
editor.commit();
|
||||
|
||||
return OnedriveCloud.aOnedriveCloud() //
|
||||
.withUsername("info@cryptomator.org") //
|
||||
.withAccessToken("authenticated") //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OnedriveTestCloud";
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package org.cryptomator.presentation.testCloud;
|
||||
|
||||
import org.cryptomator.domain.Cloud;
|
||||
import org.cryptomator.presentation.di.component.ApplicationComponent;
|
||||
|
||||
public abstract class TestCloud {
|
||||
|
||||
public abstract Cloud getInstance(ApplicationComponent appComponent);
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package org.cryptomator.presentation.testCloud;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.cryptomator.domain.Cloud;
|
||||
import org.cryptomator.domain.WebDavCloud;
|
||||
import org.cryptomator.presentation.di.component.ApplicationComponent;
|
||||
import org.cryptomator.util.crypto.CredentialCryptor;
|
||||
|
||||
public class WebdavTestCloud extends TestCloud {
|
||||
|
||||
private final Context context;
|
||||
|
||||
public WebdavTestCloud(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cloud getInstance(ApplicationComponent appComponent) {
|
||||
return WebDavCloud.aWebDavCloudCloud() //
|
||||
.withUrl("https://webdav.mc.gmx.net") //
|
||||
.withUsername("jraufelder@gmx.de") //
|
||||
.withPassword(CredentialCryptor.getInstance(context).encrypt("mG7!3B3Mx")) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WebdavTestCloud";
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
package org.cryptomator.presentation.ui;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.TypeSafeMatcher;
|
||||
|
||||
/**
|
||||
* Created by dannyroa on 5/10/15.
|
||||
*/
|
||||
public class RecyclerViewMatcher {
|
||||
|
||||
private final int recyclerViewId;
|
||||
|
||||
public RecyclerViewMatcher(int recyclerViewId) {
|
||||
this.recyclerViewId = recyclerViewId;
|
||||
}
|
||||
|
||||
public Matcher<View> atPositionOnView(final int position, final int targetViewId) {
|
||||
|
||||
return new TypeSafeMatcher<View>() {
|
||||
Resources resources = null;
|
||||
View childView;
|
||||
|
||||
public void describeTo(Description description) {
|
||||
String idDescription = Integer.toString(recyclerViewId);
|
||||
if (this.resources != null) {
|
||||
try {
|
||||
idDescription = this.resources.getResourceName(recyclerViewId);
|
||||
} catch (Resources.NotFoundException var4) {
|
||||
idDescription = String.format("%s (resource name not found)", recyclerViewId);
|
||||
}
|
||||
}
|
||||
|
||||
description.appendText("with id: " + idDescription);
|
||||
}
|
||||
|
||||
public boolean matchesSafely(View view) {
|
||||
|
||||
this.resources = view.getResources();
|
||||
|
||||
if (childView == null) {
|
||||
RecyclerView recyclerView = view.getRootView().findViewById(recyclerViewId);
|
||||
if (recyclerView != null && recyclerView.getId() == recyclerViewId) {
|
||||
childView = recyclerView.findViewHolderForAdapterPosition(position).itemView;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (targetViewId == -1) {
|
||||
return view == childView;
|
||||
} else {
|
||||
View targetView = childView.findViewById(targetViewId);
|
||||
return view == targetView;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,179 +0,0 @@
|
||||
package org.cryptomator.presentation.ui;
|
||||
|
||||
import androidx.test.espresso.ViewInteraction;
|
||||
import androidx.test.rule.ActivityTestRule;
|
||||
import androidx.test.uiautomator.UiDevice;
|
||||
import androidx.test.uiautomator.UiObjectNotFoundException;
|
||||
import androidx.test.uiautomator.UiSelector;
|
||||
|
||||
import org.cryptomator.domain.Cloud;
|
||||
import org.cryptomator.domain.CloudFolder;
|
||||
import org.cryptomator.domain.CloudNode;
|
||||
import org.cryptomator.domain.CloudType;
|
||||
import org.cryptomator.domain.Vault;
|
||||
import org.cryptomator.domain.exception.BackendException;
|
||||
import org.cryptomator.presentation.R;
|
||||
import org.cryptomator.presentation.di.component.ApplicationComponent;
|
||||
import org.hamcrest.Matchers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu;
|
||||
import static androidx.test.espresso.action.ViewActions.click;
|
||||
import static androidx.test.espresso.assertion.ViewAssertions.matches;
|
||||
import static androidx.test.espresso.matcher.RootMatchers.withDecorView;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withId;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withParent;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withText;
|
||||
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||
import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
|
||||
public class TestUtil {
|
||||
|
||||
public static final int DROPBOX = 0;
|
||||
public static final int GOOGLE_DRIVE = 1;
|
||||
public static final int ONEDRIVE = 2;
|
||||
public static final int WEBDAV = 3;
|
||||
public static final int LOCAL = 4;
|
||||
|
||||
private static final String SD_CARD_REGEX = "(?i)SD[- ]*(CARD|KARTE)";
|
||||
|
||||
public static void isToastDisplayed(String message, ActivityTestRule activityTestRule) {
|
||||
onView(withText(message)) //
|
||||
.inRoot(withDecorView(not(is(activityTestRule.getActivity().getWindow().getDecorView())))) //
|
||||
.check(matches(isDisplayed()));
|
||||
}
|
||||
|
||||
public static void openMenu(UiDevice device) {
|
||||
try {
|
||||
final UiSelector toolbar = new UiSelector() //
|
||||
.resourceId("com.android.documentsui:id/toolbar");
|
||||
|
||||
device //
|
||||
.findObject(toolbar.childSelector(new UiSelector().index(0))) //
|
||||
.click();
|
||||
} catch (UiObjectNotFoundException e) {
|
||||
throw new AssertionError("Menu not found");
|
||||
}
|
||||
}
|
||||
|
||||
public static void chooseSdCard(UiDevice device) {
|
||||
try {
|
||||
if (!sdCardAlreadySelected()) {
|
||||
openMenu(device);
|
||||
|
||||
device //
|
||||
.findObject(new UiSelector().textMatches(SD_CARD_REGEX)) //
|
||||
.click();
|
||||
}
|
||||
} catch (UiObjectNotFoundException e) {
|
||||
throw new AssertionError("Menu not found");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean sdCardAlreadySelected() {
|
||||
ViewInteraction textView = onView(allOf(withText("SDCARD"), withParent(withId(R.id.toolbar)), isDisplayed()));
|
||||
return textView.check(matches(withText("SDCARD"))) != null;
|
||||
}
|
||||
|
||||
public static void openSettings(UiDevice device) {
|
||||
awaitCompleted();
|
||||
|
||||
waitForIdle(device);
|
||||
|
||||
openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext());
|
||||
|
||||
waitForIdle(device);
|
||||
|
||||
onView(allOf( //
|
||||
withId(R.id.title), //
|
||||
withText(R.string.snack_bar_action_title_settings))) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
}
|
||||
|
||||
public static void waitForIdle(UiDevice uiDevice) {
|
||||
uiDevice.waitForIdle();
|
||||
}
|
||||
|
||||
public static void addFolderInCloud(ApplicationComponent appComponent, String path, CloudType cloudType) {
|
||||
try {
|
||||
CloudFolder vaultFolder = (CloudFolder) getNode(appComponent, getEncryptedCloud(appComponent, cloudType), path);
|
||||
|
||||
if (!appComponent.cloudContentRepository().exists(vaultFolder)) {
|
||||
assertThat(appComponent.cloudContentRepository().create(vaultFolder), Matchers.is(notNullValue()));
|
||||
}
|
||||
} catch (BackendException e) {
|
||||
throw new AssertionError("Error while adding testVault");
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeFolderInCloud(ApplicationComponent appComponent, String path, CloudType cloudType) {
|
||||
try {
|
||||
CloudFolder vaultFolder = (CloudFolder) getNode(appComponent, getEncryptedCloud(appComponent, cloudType), path);
|
||||
|
||||
if (appComponent.cloudContentRepository().exists(vaultFolder)) {
|
||||
appComponent.cloudContentRepository().delete(vaultFolder);
|
||||
}
|
||||
} catch (BackendException e) {
|
||||
throw new AssertionError("Error while removing testVault");
|
||||
}
|
||||
}
|
||||
|
||||
private static Cloud getEncryptedCloud(ApplicationComponent appComponent, CloudType cloudType) throws BackendException {
|
||||
Cloud cloud;
|
||||
if (cloudType.equals(CloudType.LOCAL)) {
|
||||
cloud = appComponent.cloudRepository().clouds(cloudType).get(1);
|
||||
} else {
|
||||
cloud = appComponent.cloudRepository().clouds(cloudType).get(0);
|
||||
}
|
||||
|
||||
return cloud;
|
||||
}
|
||||
|
||||
private static CloudNode getNode(ApplicationComponent appComponent, Cloud cloud, String path) throws BackendException {
|
||||
return appComponent.cloudContentRepository().resolve(cloud, path);
|
||||
}
|
||||
|
||||
public static void removeFolderInVault(ApplicationComponent appComponent, String name, CloudType cloudType) {
|
||||
try {
|
||||
Cloud decryptedCloud = getDecryptedCloud(appComponent, cloudType);
|
||||
CloudFolder root = appComponent.cloudContentRepository().root(decryptedCloud);
|
||||
CloudFolder folder = appComponent.cloudContentRepository().folder(root, name);
|
||||
appComponent.cloudContentRepository().delete(folder);
|
||||
} catch (BackendException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addFolderInVaultsRoot(ApplicationComponent appComponent, String name, CloudType cloudType) {
|
||||
try {
|
||||
Cloud decryptedCloud = getDecryptedCloud(appComponent, cloudType);
|
||||
CloudFolder root = appComponent.cloudContentRepository().root(decryptedCloud);
|
||||
CloudFolder folder = appComponent.cloudContentRepository().folder(root, name);
|
||||
assertThat(appComponent.cloudContentRepository().create(folder), is(notNullValue()));
|
||||
} catch (BackendException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Cloud getDecryptedCloud(ApplicationComponent appComponent, CloudType cloudType) throws BackendException {
|
||||
List<Vault> vaults = appComponent.vaultRepository().vaults();
|
||||
for (Vault vault : vaults) {
|
||||
if (vault.getCloudType().equals(cloudType)) {
|
||||
return appComponent.cloudRepository().decryptedViewOf(vault);
|
||||
}
|
||||
}
|
||||
|
||||
throw new AssertionError("Cloud for vault not found");
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package org.cryptomator.presentation.ui.activity;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.uiautomator.UiDevice;
|
||||
|
||||
import org.cryptomator.presentation.R;
|
||||
import org.cryptomator.presentation.ui.RecyclerViewMatcher;
|
||||
|
||||
import static androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.action.ViewActions.click;
|
||||
import static androidx.test.espresso.assertion.ViewAssertions.matches;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withId;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withText;
|
||||
import static java.lang.String.format;
|
||||
import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
|
||||
public class BasicNodeOperationsUtil {
|
||||
|
||||
static void openSettings(UiDevice device, int nodePosition) {
|
||||
awaitCompleted();
|
||||
|
||||
waitForIdle(device);
|
||||
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(nodePosition, R.id.settings)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
static void waitForIdle(UiDevice uiDevice) {
|
||||
uiDevice.waitForIdle();
|
||||
}
|
||||
|
||||
static void checkEmptyFolderHint() {
|
||||
awaitCompleted();
|
||||
|
||||
onView(allOf( //
|
||||
withId(R.id.tv_empty_folder_hint), //
|
||||
withText(R.string.screen_file_browser_msg_empty_folder))) //
|
||||
.check(matches(withText(R.string.screen_file_browser_msg_empty_folder)));
|
||||
}
|
||||
|
||||
static void checkFileOrFolderAlreadyExistsErrorMessage(String nodeName) {
|
||||
onView(withId(R.id.tv_error)) //
|
||||
.check(matches(withText(format( //
|
||||
InstrumentationRegistry //
|
||||
.getTargetContext() //
|
||||
.getString(R.string.error_file_or_folder_exists), //
|
||||
nodeName))));
|
||||
}
|
||||
|
||||
public static RecyclerViewMatcher withRecyclerView(final int recyclerViewId) {
|
||||
return new RecyclerViewMatcher(recyclerViewId);
|
||||
}
|
||||
}
|
@ -1,248 +0,0 @@
|
||||
package org.cryptomator.presentation.ui.activity;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.espresso.ViewInteraction;
|
||||
import androidx.test.espresso.contrib.RecyclerViewActions;
|
||||
import androidx.test.rule.ActivityTestRule;
|
||||
import androidx.test.uiautomator.UiDevice;
|
||||
import androidx.test.uiautomator.UiObject;
|
||||
import androidx.test.uiautomator.UiObjectNotFoundException;
|
||||
import androidx.test.uiautomator.UiScrollable;
|
||||
import androidx.test.uiautomator.UiSelector;
|
||||
|
||||
import org.cryptomator.presentation.R;
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.TypeSafeMatcher;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runners.MethodSorters;
|
||||
|
||||
import static androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.action.ViewActions.click;
|
||||
import static androidx.test.espresso.assertion.ViewAssertions.matches;
|
||||
import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withChild;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withId;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withText;
|
||||
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||
import static java.lang.Thread.sleep;
|
||||
import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.DROPBOX;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.GOOGLE_DRIVE;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.LOCAL;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.ONEDRIVE;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.WEBDAV;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.openSettings;
|
||||
import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.withRecyclerView;
|
||||
import static org.hamcrest.core.AllOf.allOf;
|
||||
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class CloudsOperationsTest {
|
||||
|
||||
private final UiDevice device = UiDevice.getInstance(getInstrumentation());
|
||||
@Rule
|
||||
public ActivityTestRule<SplashActivity> activityTestRule //
|
||||
= new ActivityTestRule<>(SplashActivity.class);
|
||||
|
||||
public static void openCloudServices(UiDevice device) {
|
||||
openSettings(device);
|
||||
|
||||
ViewInteraction recyclerView = onView(allOf(withId(R.id.recycler_view), childAtPosition(withId(android.R.id.list_container), 0)));
|
||||
recyclerView.perform(RecyclerViewActions.actionOnItemAtPosition(3, click()));
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
public static void checkLoginResult(String cloudName, int cloudPosition) {
|
||||
String displayText = InstrumentationRegistry //
|
||||
.getTargetContext() //
|
||||
.getString(R.string.screen_cloud_settings_sign_out_from_cloud) + " " + cloudName;
|
||||
|
||||
UiObject signOutText = UiDevice.getInstance(getInstrumentation()).findObject(new UiSelector().text(displayText));
|
||||
signOutText.waitForExists(15000);
|
||||
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(cloudPosition, R.id.cloudName)) //
|
||||
.check(matches(withText(displayText)));
|
||||
}
|
||||
|
||||
private static Matcher<View> childAtPosition(final Matcher<View> parentMatcher, final int position) {
|
||||
|
||||
return new TypeSafeMatcher<View>() {
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("Child at position " + position + " in parent ");
|
||||
parentMatcher.describeTo(description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesSafely(View view) {
|
||||
ViewParent parent = view.getParent();
|
||||
return parent instanceof ViewGroup && parentMatcher.matches(parent) //
|
||||
&& view.equals(((ViewGroup) parent).getChildAt(position));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test01EnableDebugModeLeadsToDebugMode() {
|
||||
openSettings(device);
|
||||
|
||||
try {
|
||||
new UiScrollable(new UiSelector().scrollable(true)).scrollToEnd(10);
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withChild(withText(R.string.screen_settings_debug_mode_label))) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(android.R.id.button1)) //
|
||||
.perform(click());
|
||||
} catch (UiObjectNotFoundException e) {
|
||||
throw new AssertionError("Scrolling down failed");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test02LoginDropboxCloudLeadsToLoggedInDropboxCloud() {
|
||||
openCloudServices(device);
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(DROPBOX, click()));
|
||||
|
||||
try {
|
||||
device //
|
||||
.findObject(new UiSelector().resourceId("android:id/button_once")) //
|
||||
.click();
|
||||
|
||||
device.waitForIdle();
|
||||
|
||||
device //
|
||||
.findObject(new UiSelector().text("Email")) //
|
||||
.setText("");
|
||||
|
||||
device //
|
||||
.findObject(new UiSelector().text("Password")) //
|
||||
.setText("");
|
||||
|
||||
device //
|
||||
.findObject(new UiSelector().description("Sign in")) //
|
||||
.click();
|
||||
|
||||
device.waitForIdle();
|
||||
|
||||
device //
|
||||
.findObject(new UiSelector().description("Allow")) //
|
||||
.click();
|
||||
|
||||
} catch (UiObjectNotFoundException e) {
|
||||
throw new AssertionError("Dropbox login failed");
|
||||
}
|
||||
|
||||
device.waitForIdle();
|
||||
|
||||
checkLoginResult("Dropbox", DROPBOX);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test03LoginGoogleDriveCloudLeadsToLoggedInGoogleDriveCloud() {
|
||||
openCloudServices(device);
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(GOOGLE_DRIVE, click()));
|
||||
|
||||
try {
|
||||
device //
|
||||
.findObject(new UiSelector().resourceId("android:id/text1")) //
|
||||
.click();
|
||||
|
||||
device //
|
||||
.findObject(new UiSelector().resourceId("android:id/button1")) //
|
||||
.click();
|
||||
} catch (UiObjectNotFoundException e) {
|
||||
throw new AssertionError("GoogleDrive login failed");
|
||||
}
|
||||
|
||||
device.waitForIdle();
|
||||
|
||||
checkLoginResult("Google Drive", GOOGLE_DRIVE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test04LoginOneDriveLeadsToLoggedInOneDriveCloud() {
|
||||
openCloudServices(device);
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(ONEDRIVE, click()));
|
||||
|
||||
try {
|
||||
try {
|
||||
sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
device //
|
||||
.findObject(new UiSelector().resourceId("i0116")) //
|
||||
.setText("");
|
||||
|
||||
device //
|
||||
.findObject(new UiSelector().resourceId("idSIButton9")) //
|
||||
.click();
|
||||
|
||||
device.waitForWindowUpdate(null, 500);
|
||||
|
||||
device //
|
||||
.findObject(new UiSelector().resourceId("i0118")) //
|
||||
.setText("");
|
||||
|
||||
device.waitForWindowUpdate(null, 500);
|
||||
|
||||
device //
|
||||
.findObject(new UiSelector().resourceId("idSIButton9")) //
|
||||
.click();
|
||||
|
||||
try {
|
||||
device //
|
||||
.findObject(new UiSelector().resourceId("idSIButton9")) //
|
||||
.click();
|
||||
} catch (UiObjectNotFoundException e) {
|
||||
// Do nothing because second click is normaly not necessary
|
||||
}
|
||||
} catch (UiObjectNotFoundException e) {
|
||||
throw new AssertionError("OneDrive login failed");
|
||||
}
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
checkLoginResult("OneDrive", ONEDRIVE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test05LoginWebdavCloudLeadsToLoggedInWebdavCloud() {
|
||||
openCloudServices(device);
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(WEBDAV, click()));
|
||||
|
||||
LoginWebdavClouds.loginWebdavClouds(activityTestRule.getActivity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test06LoginLocalCloudLeadsToLoggedInLocalCloud() {
|
||||
openCloudServices(device);
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(LOCAL, click()));
|
||||
|
||||
LoginLocalClouds.loginLocalClouds(device);
|
||||
}
|
||||
}
|
@ -1,668 +0,0 @@
|
||||
package org.cryptomator.presentation.ui.activity;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.rule.ActivityTestRule;
|
||||
import androidx.test.uiautomator.UiDevice;
|
||||
import androidx.test.uiautomator.UiObjectNotFoundException;
|
||||
import androidx.test.uiautomator.UiSelector;
|
||||
|
||||
import org.cryptomator.domain.CloudType;
|
||||
import org.cryptomator.presentation.CryptomatorApp;
|
||||
import org.cryptomator.presentation.R;
|
||||
import org.cryptomator.presentation.di.component.ApplicationComponent;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static android.R.id.button1;
|
||||
import static androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.Espresso.pressBack;
|
||||
import static androidx.test.espresso.action.ViewActions.click;
|
||||
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
|
||||
import static androidx.test.espresso.action.ViewActions.replaceText;
|
||||
import static androidx.test.espresso.action.ViewActions.swipeDown;
|
||||
import static androidx.test.espresso.assertion.ViewAssertions.matches;
|
||||
import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withId;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withText;
|
||||
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||
import static java.lang.String.format;
|
||||
import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.DROPBOX;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.GOOGLE_DRIVE;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.LOCAL;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.ONEDRIVE;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.WEBDAV;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.addFolderInVaultsRoot;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.chooseSdCard;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.isToastDisplayed;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.removeFolderInVault;
|
||||
import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.checkEmptyFolderHint;
|
||||
import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.checkFileOrFolderAlreadyExistsErrorMessage;
|
||||
import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.openSettings;
|
||||
import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.withRecyclerView;
|
||||
import static org.cryptomator.presentation.ui.activity.FolderOperationsTest.openFolder;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assume.assumeThat;
|
||||
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@RunWith(Parameterized.class)
|
||||
public class FileOperationsTest {
|
||||
|
||||
private final UiDevice device = UiDevice.getInstance(getInstrumentation());
|
||||
private final Context context = InstrumentationRegistry.getTargetContext();
|
||||
private final Integer cloudId;
|
||||
@Rule
|
||||
public ActivityTestRule<SplashActivity> activityTestRule //
|
||||
= new ActivityTestRule<>(SplashActivity.class);
|
||||
private String packageName;
|
||||
|
||||
public FileOperationsTest(Integer cloudId, String cloudName) {
|
||||
this.cloudId = cloudId;
|
||||
}
|
||||
|
||||
@Parameterized.Parameters(name = "{1}")
|
||||
public static Iterable<Object[]> data() {
|
||||
return Arrays.asList(new Object[][] {{DROPBOX, "DROPBOX"}, {GOOGLE_DRIVE, "GOOGLE_DRIVE"}, {ONEDRIVE, "ONEDRIVE"}, {WEBDAV, "WEBDAV"}, {LOCAL, "LOCAL"}});
|
||||
}
|
||||
|
||||
static void isPermissionShown(UiDevice device) {
|
||||
if (!device //
|
||||
.findObject(new UiSelector().text("ALLOW")) //
|
||||
.waitForExists(1000L)) {
|
||||
throw new AssertionError("View with text <???> not found!");
|
||||
}
|
||||
}
|
||||
|
||||
static void grantPermission(UiDevice device) {
|
||||
try {
|
||||
device //
|
||||
.findObject(new UiSelector().text("ALLOW")) //
|
||||
.click();
|
||||
} catch (UiObjectNotFoundException e) {
|
||||
throw new AssertionError("Permission not found");
|
||||
}
|
||||
}
|
||||
|
||||
static void openFile(int nodePosition) {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(nodePosition, R.id.cloudFileText)) //
|
||||
.perform(click());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test00UploadFileWithCancelPressedWhileUploadingLeadsToNoNewFileInVault() {
|
||||
assumeThat(cloudId, is(not(LOCAL)));
|
||||
|
||||
packageName = activityTestRule.getActivity().getPackageName();
|
||||
|
||||
String nodeName = "foo.pdf";
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
uploadFile(nodeName);
|
||||
|
||||
onView(withId(android.R.id.button3)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(swipeDown());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
try {
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(1, R.id.cloudFileText)) //
|
||||
.check(matches(withText(nodeName)));
|
||||
|
||||
throw new AssertionError("Canceling the upload should not lead to new cloud node");
|
||||
} catch (NullPointerException e) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test01UploadFileLeadsToNewFileInVault() {
|
||||
packageName = activityTestRule.getActivity().getPackageName();
|
||||
String nodeName = "lala.png";
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
uploadFile(nodeName);
|
||||
|
||||
device.waitForWindowUpdate(packageName, 15000);
|
||||
|
||||
checkFileDisplayText(nodeName, 1);
|
||||
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test02UploadAlreadyExistingFileAndCancelLeadsToNoNewFileInVault() {
|
||||
String nodeName = "lala.png";
|
||||
String subString;
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
// subString = subtextFromFile();
|
||||
|
||||
uploadFile(nodeName);
|
||||
|
||||
device.waitForWindowUpdate(packageName, 500);
|
||||
|
||||
onView(withText(R.string.dialog_button_cancel)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
// assertThat(subtextFromFile(), equalTo(subString));
|
||||
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test03UploadAlreadyExistingFileAndReplaceLeadsToUpdatedFileInVault() {
|
||||
String nodeName = "lala.png";
|
||||
String subString;
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
subString = subtextFromFile();
|
||||
|
||||
uploadFile(nodeName);
|
||||
|
||||
device.waitForWindowUpdate(packageName, 500);
|
||||
|
||||
onView(withText(R.string.dialog_existing_file_positive_button)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
// assertThat(subtextFromFile(), not(equalTo(subString)));
|
||||
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test04OpenFileLeadsToOpenFile() {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
openFile(1);
|
||||
|
||||
device.waitForWindowUpdate(null, 25000);
|
||||
|
||||
device.pressBack();
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test05RenameFileLeadsToFileWithNewName() {
|
||||
String fileName = "foo.png";
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
renameFileTo(fileName, 1);
|
||||
|
||||
checkFileDisplayText(fileName, 1);
|
||||
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test06RenameFileToExistingFolderLeadsToNothingChanged() {
|
||||
String fileName = "testFolder";
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
renameFileTo(fileName, 1);
|
||||
|
||||
checkFileOrFolderAlreadyExistsErrorMessage(fileName);
|
||||
|
||||
onView(withId(android.R.id.button2)) //
|
||||
.perform(click());
|
||||
|
||||
checkFileDisplayText("foo.png", 1);
|
||||
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test07MoveFileLeadsToFileWithNewLocation() {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
openSettings(device, 1);
|
||||
|
||||
openMoveFile();
|
||||
|
||||
openFolder(0);
|
||||
|
||||
onView(withId(R.id.chooseLocationButton)) //
|
||||
.perform(click());
|
||||
|
||||
openFolder(0);
|
||||
|
||||
checkFileDisplayText("foo.png", 0);
|
||||
|
||||
pressBack();
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test08MoveWithExistingFileLeadsToNoNewFile() {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
openFolder(0);
|
||||
|
||||
openSettings(device, 0);
|
||||
|
||||
openMoveFile();
|
||||
|
||||
onView(withId(R.id.chooseLocationButton)) //
|
||||
.perform(click());
|
||||
|
||||
isToastDisplayed( //
|
||||
format( //
|
||||
InstrumentationRegistry //
|
||||
.getTargetContext() //
|
||||
.getString(R.string.error_file_or_folder_exists), //
|
||||
"foo.png"), //
|
||||
activityTestRule);
|
||||
|
||||
pressBack();
|
||||
pressBack();
|
||||
pressBack();
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test09MoveWithExistingFolderLeadsToNoNewFile() {
|
||||
ApplicationComponent appComponent = ((CryptomatorApp) activityTestRule.getActivity().getApplication()).getComponent();
|
||||
|
||||
String moveFileNameAndTmpFolder = "foo.png";
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
addFolderInVaultsRoot(appComponent, moveFileNameAndTmpFolder, CloudType.values()[cloudId]);
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
refreshCloudNodes();
|
||||
|
||||
openFolder(1);
|
||||
|
||||
openSettings(device, 0);
|
||||
|
||||
openMoveFile();
|
||||
|
||||
pressBack();
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.chooseLocationButton)) //
|
||||
.perform(click());
|
||||
|
||||
isToastDisplayed( //
|
||||
InstrumentationRegistry //
|
||||
.getTargetContext() //
|
||||
.getString(R.string.error_file_or_folder_exists), //
|
||||
activityTestRule);
|
||||
|
||||
removeFolderInVault(appComponent, moveFileNameAndTmpFolder, CloudType.values()[cloudId]);
|
||||
|
||||
pressBack();
|
||||
pressBack();
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test10ShareFileWithCryptomatorLeadsToNewFileInVault() {
|
||||
String newFileName = "fooBar.png";
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
openFolder(0);
|
||||
|
||||
shareFile(newFileName, cloudId, 0);
|
||||
|
||||
isToastDisplayed(context.getString(R.string.screen_share_files_msg_success), activityTestRule);
|
||||
|
||||
refreshCloudNodes();
|
||||
|
||||
checkFileDisplayText(newFileName, 1);
|
||||
|
||||
pressBack();
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test11ShareExistingFileAndReplaceWithCryptomatorLeadsToUpdatedFileInVault() {
|
||||
String newFileName = "fooBar.png";
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
openFolder(0);
|
||||
|
||||
shareFile(newFileName, cloudId, 0);
|
||||
|
||||
onView(withId(android.R.id.button1)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
isToastDisplayed(context.getString(R.string.screen_share_files_msg_success), activityTestRule);
|
||||
|
||||
refreshCloudNodes();
|
||||
|
||||
checkFileDisplayText(newFileName, 1); // check before and compare with after upload
|
||||
|
||||
pressBack();
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test12ShareExistingFileWithoutReplaceWithCryptomatorLeadsToNotUpdatedFileInVault() {
|
||||
String newFileName = "fooBar.png";
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
openFolder(0);
|
||||
|
||||
shareFile(newFileName, cloudId, 0);
|
||||
|
||||
onView(withId(android.R.id.button3)) //
|
||||
.perform(click());
|
||||
|
||||
pressBack();
|
||||
pressBack();
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test13RenameFileToExistingFileLeadsToNothingChanged() {
|
||||
String fileName = "fooBar.png";
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
openFolder(0);
|
||||
|
||||
renameFileTo(fileName, 0);
|
||||
|
||||
checkFileOrFolderAlreadyExistsErrorMessage(fileName);
|
||||
|
||||
onView(withId(android.R.id.button2)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
checkFileDisplayText("foo.png", 0);
|
||||
|
||||
pressBack();
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test14DeleteFileLeadsToRemovedFile() {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
openFolder(0);
|
||||
|
||||
deleteNodeOnPosition(0);
|
||||
awaitCompleted();
|
||||
deleteNodeOnPosition(0);
|
||||
|
||||
checkEmptyFolderHint();
|
||||
|
||||
pressBack();
|
||||
|
||||
deleteTestFolder();
|
||||
|
||||
pressBack();
|
||||
}
|
||||
|
||||
private void deleteNodeOnPosition(int position) {
|
||||
openSettings(device, position);
|
||||
|
||||
onView(withId(R.id.delete_file)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(android.R.id.button1)) //
|
||||
.perform(click());
|
||||
}
|
||||
|
||||
private void refreshCloudNodes() {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(swipeDown());
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
private void shareFile(String newFilename, int vaultPosition, int filePosition) {
|
||||
awaitCompleted();
|
||||
|
||||
openSettings(device, filePosition);
|
||||
|
||||
openEncryptWithCryptomator();
|
||||
|
||||
chooseShareLocation(vaultPosition);
|
||||
|
||||
checkPathInSharingScreen("/testFolder", vaultPosition);
|
||||
|
||||
onView(withId(R.id.fileName)) //
|
||||
.perform(replaceText(newFilename), closeSoftKeyboard());
|
||||
|
||||
onView(withId(R.id.saveFiles)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
private void chooseShareLocation(int nodePosition) {
|
||||
onView(withRecyclerView(R.id.locationsRecyclerView) //
|
||||
.atPositionOnView(nodePosition, R.id.vaultName)) //
|
||||
.perform(click());
|
||||
|
||||
device.waitForWindowUpdate(packageName, 300);
|
||||
|
||||
onView(withRecyclerView(R.id.locationsRecyclerView) //
|
||||
.atPositionOnView(nodePosition, R.id.chooseFolderLocation)) //
|
||||
.perform(click());
|
||||
|
||||
openFolder(0);
|
||||
|
||||
onView(withId(R.id.chooseLocationButton)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
private void checkPathInSharingScreen(String path, int nodePosition) {
|
||||
onView(withRecyclerView(R.id.locationsRecyclerView) //
|
||||
.atPositionOnView(nodePosition, R.id.chosenLocation)) //
|
||||
.check(matches(withText(path)));
|
||||
}
|
||||
|
||||
private void deleteTestFolder() {
|
||||
awaitCompleted();
|
||||
|
||||
openSettings(device, 0);
|
||||
|
||||
onView(withId(R.id.delete_folder)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(android.R.id.button1)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
checkEmptyFolderHint();
|
||||
}
|
||||
|
||||
private void uploadFile(String nodeName) {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.floatingActionButton)) //
|
||||
.perform(click());
|
||||
|
||||
onView(withId(R.id.upload_files)) //
|
||||
.perform(click());
|
||||
|
||||
chooseSdCard(device);
|
||||
|
||||
try {
|
||||
device //
|
||||
.findObject(new UiSelector().text(nodeName)) //
|
||||
.click();
|
||||
} catch (UiObjectNotFoundException e) {
|
||||
throw new AssertionError("Image " + nodeName + " not available");
|
||||
}
|
||||
}
|
||||
|
||||
private void renameFileTo(String name, int nodePosition) {
|
||||
awaitCompleted();
|
||||
|
||||
openSettings(device, nodePosition);
|
||||
|
||||
onView(withId(R.id.rename_file)) //
|
||||
.perform(click());
|
||||
|
||||
onView(withId(R.id.et_rename)) //
|
||||
.perform(replaceText(name), closeSoftKeyboard());
|
||||
|
||||
onView(allOf( //
|
||||
withId(button1), //
|
||||
withText(R.string.dialog_rename_node_positive_button))) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
private void checkFileDisplayText(String assertNodeText, int nodePosition) {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(nodePosition, R.id.cloudFileText)) //
|
||||
.check(matches(withText(assertNodeText)));
|
||||
}
|
||||
|
||||
private void openMoveFile() {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.move_file)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
private void openEncryptWithCryptomator() {
|
||||
openShareFile();
|
||||
try {
|
||||
device //
|
||||
.findObject(new UiSelector().text(context.getString(R.string.share_with_label))) //
|
||||
.waitForExists(30000L);
|
||||
device //
|
||||
.findObject(new UiSelector().text(context.getString(R.string.share_with_label))) //
|
||||
.click();
|
||||
} catch (UiObjectNotFoundException e) {
|
||||
throw new AssertionError("Share with Cryptomator not available");
|
||||
}
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
private void openShareFile() {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.share_file)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
private String subtextFromFile() {
|
||||
try {
|
||||
final UiSelector docList = new UiSelector() //
|
||||
.resourceId("org.cryptomator:id/cloudFileContent");
|
||||
|
||||
return device //
|
||||
.findObject(docList.childSelector(new UiSelector(). //
|
||||
resourceId("org.cryptomator:id/cloudFileSubText") //
|
||||
.index(0))) //
|
||||
.getText();
|
||||
} catch (UiObjectNotFoundException e) {
|
||||
throw new AssertionError("Folder 0 not found");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,313 +0,0 @@
|
||||
package org.cryptomator.presentation.ui.activity;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.rule.ActivityTestRule;
|
||||
import androidx.test.uiautomator.UiDevice;
|
||||
|
||||
import org.cryptomator.presentation.R;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.Espresso.pressBack;
|
||||
import static androidx.test.espresso.action.ViewActions.click;
|
||||
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
|
||||
import static androidx.test.espresso.action.ViewActions.replaceText;
|
||||
import static androidx.test.espresso.assertion.ViewAssertions.matches;
|
||||
import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withId;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withText;
|
||||
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||
import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.DROPBOX;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.GOOGLE_DRIVE;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.LOCAL;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.ONEDRIVE;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.WEBDAV;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.isToastDisplayed;
|
||||
import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.checkEmptyFolderHint;
|
||||
import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.checkFileOrFolderAlreadyExistsErrorMessage;
|
||||
import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.openSettings;
|
||||
import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.withRecyclerView;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@RunWith(Parameterized.class)
|
||||
public class FolderOperationsTest {
|
||||
|
||||
private final UiDevice device = UiDevice.getInstance(getInstrumentation());
|
||||
private final Context context = InstrumentationRegistry.getTargetContext();
|
||||
private final Integer cloudId;
|
||||
@Rule
|
||||
public ActivityTestRule<SplashActivity> activityTestRule //
|
||||
= new ActivityTestRule<>(SplashActivity.class);
|
||||
|
||||
public FolderOperationsTest(Integer cloudId, String cloudName) {
|
||||
this.cloudId = cloudId;
|
||||
}
|
||||
|
||||
@Parameterized.Parameters(name = "{1}")
|
||||
public static Iterable<Object[]> data() {
|
||||
return Arrays.asList(new Object[][] {{DROPBOX, "DROPBOX"}, {GOOGLE_DRIVE, "GOOGLE_DRIVE"}, {ONEDRIVE, "ONEDRIVE"}, {WEBDAV, "WEBDAV"}, {LOCAL, "LOCAL"}});
|
||||
}
|
||||
|
||||
static void openFolder(int nodePosition) {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(nodePosition, R.id.cloudFolderText)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test00CreateFolderLeadsToFolderInVault() {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
String folderName = "testFolder";
|
||||
createFolder(folderName);
|
||||
|
||||
checkFolderCreationResult(folderName, "/0/testVault", 0);
|
||||
pressBack();
|
||||
|
||||
folderName = "testFolder1";
|
||||
createFolder(folderName);
|
||||
|
||||
checkFolderCreationResult(folderName, "/0/testVault", 1);
|
||||
|
||||
pressBack();
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test01CreateExistingFolderLeadsToNoNewFolderInVault() {
|
||||
String folderName = "testFolder";
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
createFolder(folderName);
|
||||
|
||||
checkFileOrFolderAlreadyExistsErrorMessage(folderName);
|
||||
|
||||
onView(withId(android.R.id.button2)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test02OpenFolderLeadsToOpenFolder() {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
openFolder(0);
|
||||
|
||||
checkEmptyFolderHint();
|
||||
|
||||
pressBack();
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test03RenameFolderLeadsToFolderWithNewName() {
|
||||
String newFolderName = "testFolder2";
|
||||
int nodePosition = 1;
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
renameFolderTo(newFolderName, nodePosition);
|
||||
|
||||
checkFolderDisplayText(newFolderName, nodePosition);
|
||||
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test04RenameFolderToAlreadyExistFolderLeadsToSameFolderName() {
|
||||
String newFolderName = "testFolder";
|
||||
int nodePosition = 1;
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
renameFolderTo(newFolderName, nodePosition);
|
||||
|
||||
checkFileOrFolderAlreadyExistsErrorMessage(newFolderName);
|
||||
|
||||
onView(withId(android.R.id.button2)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test05MoveFolderLeadsToFolderWithNewLocation() {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
openSettings(device, 1);
|
||||
|
||||
openMoveFolder();
|
||||
|
||||
openFolder(0);
|
||||
|
||||
onView(withId(R.id.chooseLocationButton)) //
|
||||
.perform(click());
|
||||
|
||||
openFolder(0);
|
||||
|
||||
checkFolderDisplayText("testFolder2", 0);
|
||||
|
||||
openFolder(0);
|
||||
|
||||
checkEmptyFolderHint();
|
||||
|
||||
pressBack();
|
||||
pressBack();
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test06MoveFolderToAlreadyExistingFolderLeadsToErrorMessage() {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
openSettings(device, 0);
|
||||
|
||||
openMoveFolder();
|
||||
|
||||
onView(withId(R.id.chooseLocationButton)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
isToastDisplayed( //
|
||||
context.getString(R.string.error_file_or_folder_exists), //
|
||||
activityTestRule);
|
||||
|
||||
pressBack();
|
||||
pressBack();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test07DeleteFolderLeadsToRemovedFolder() {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.recyclerView)) //
|
||||
.perform(actionOnItemAtPosition(cloudId, click()));
|
||||
|
||||
openFolder(0);
|
||||
|
||||
openSettings(device, 0);
|
||||
|
||||
onView(withId(R.id.delete_folder)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(android.R.id.button1)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
checkEmptyFolderHint();
|
||||
|
||||
pressBack();
|
||||
pressBack();
|
||||
}
|
||||
|
||||
private void openMoveFolder() {
|
||||
onView(withId(R.id.move_folder)) //
|
||||
.perform(click());
|
||||
}
|
||||
|
||||
private void createFolder(String name) {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.floatingActionButton)) //
|
||||
.perform(click());
|
||||
|
||||
onView(withId(R.id.create_new_folder)) //
|
||||
.perform(click());
|
||||
|
||||
onView(withId(R.id.et_folder_name)) //
|
||||
.perform(replaceText(name), closeSoftKeyboard());
|
||||
|
||||
onView(allOf( //
|
||||
withId(android.R.id.button1), //
|
||||
withText(R.string.screen_enter_vault_name_button_text))) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
private void checkFolderCreationResult(String folderName, String path, int position) {
|
||||
checkFolderDisplayText(folderName, position);
|
||||
|
||||
openSettings(device, position);
|
||||
|
||||
onView(allOf( //
|
||||
withId(R.id.tv_folder_path), //
|
||||
withText(path))) //
|
||||
.check(matches(withText(path)));
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
private void renameFolderTo(String name, int nodePosition) {
|
||||
awaitCompleted();
|
||||
|
||||
openSettings(device, nodePosition);
|
||||
|
||||
onView(withId(R.id.change_cloud)) //
|
||||
.perform(click());
|
||||
|
||||
onView(withId(R.id.et_rename)) //
|
||||
.perform(replaceText(name), closeSoftKeyboard());
|
||||
|
||||
onView(allOf( //
|
||||
withId(android.R.id.button1), //
|
||||
withText(R.string.dialog_rename_node_positive_button))) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
private void checkFolderDisplayText(String assertNodeText, int nodePosition) {
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(nodePosition, R.id.cloudFolderText)) //
|
||||
.check(matches(withText(assertNodeText)));
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package org.cryptomator.presentation.ui.activity;
|
||||
|
||||
import androidx.test.uiautomator.UiDevice;
|
||||
import androidx.test.uiautomator.UiObjectNotFoundException;
|
||||
import androidx.test.uiautomator.UiSelector;
|
||||
|
||||
import org.cryptomator.presentation.R;
|
||||
|
||||
import static androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.action.ViewActions.click;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withId;
|
||||
import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.chooseSdCard;
|
||||
import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.withRecyclerView;
|
||||
|
||||
public class LoginLocalClouds {
|
||||
|
||||
private static UiDevice device;
|
||||
|
||||
public static void loginLocalClouds(UiDevice uiDevice) {
|
||||
device = uiDevice;
|
||||
String folderName = "0";
|
||||
createNewStorageAccessCloudCloud(folderName);
|
||||
awaitCompleted();
|
||||
checkResult(folderName);
|
||||
}
|
||||
|
||||
private static void createNewStorageAccessCloudCloud(String folderName) {
|
||||
onView(withId(R.id.floating_action_button)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
chooseSdCard(device);
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
openFolder0();
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
chooseFolder(device);
|
||||
}
|
||||
|
||||
private static void openFolder0() {
|
||||
try {
|
||||
final UiSelector docList = new UiSelector() //
|
||||
.resourceId("com.android.documentsui:id/container_directory") //
|
||||
.childSelector( //
|
||||
new UiSelector() //
|
||||
.resourceId("com.android.documentsui:id/dir_list"));
|
||||
|
||||
device //
|
||||
.findObject(docList.childSelector(new UiSelector().text("0"))) //
|
||||
.click();
|
||||
} catch (UiObjectNotFoundException e) {
|
||||
throw new AssertionError("Folder 0 not found");
|
||||
}
|
||||
}
|
||||
|
||||
public static void chooseFolder(UiDevice device) {
|
||||
try {
|
||||
|
||||
final UiSelector docList = new UiSelector() //
|
||||
.resourceId("com.android.documentsui:id/container_save");
|
||||
|
||||
device //
|
||||
.findObject(docList.childSelector(new UiSelector().resourceId("android:id/button1"))) //
|
||||
.click();
|
||||
} catch (UiObjectNotFoundException e) {
|
||||
throw new AssertionError("Folder 0 not found");
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkResult(String folderName) {
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(0, R.id.cloudText)) //
|
||||
.perform(click());
|
||||
}
|
||||
}
|
@ -1,168 +0,0 @@
|
||||
package org.cryptomator.presentation.ui.activity;
|
||||
|
||||
import org.cryptomator.presentation.R;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.action.ViewActions.click;
|
||||
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
|
||||
import static androidx.test.espresso.action.ViewActions.pressBack;
|
||||
import static androidx.test.espresso.action.ViewActions.replaceText;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withId;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withText;
|
||||
import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted;
|
||||
import static org.cryptomator.presentation.ui.activity.LoginWebdavClouds.WebdavCloudCredentials.notSpecialWebdavClouds;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
|
||||
class LoginWebdavClouds {
|
||||
|
||||
private static final String localUrl = "192.168.0.108";
|
||||
|
||||
static void loginWebdavClouds(SplashActivity activity) {
|
||||
loginStandardWebdavClouds();
|
||||
|
||||
/*
|
||||
* loginAuthenticationFailWebdavCloud(activity);
|
||||
*
|
||||
* loginSelfSignedWebdavCloud();
|
||||
*
|
||||
* loginRedirectToHttpsWebdavCloud();
|
||||
*
|
||||
* loginRedirectToUrlWebdavCloud();
|
||||
*/
|
||||
}
|
||||
|
||||
private static void loginStandardWebdavClouds() {
|
||||
for (WebdavCloudCredentials webdavCloudCredential : notSpecialWebdavClouds()) {
|
||||
createNewCloud();
|
||||
|
||||
enterCredentials(webdavCloudCredential);
|
||||
|
||||
startLoginProcess();
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
checkResult(webdavCloudCredential);
|
||||
}
|
||||
|
||||
pressBack();
|
||||
}
|
||||
|
||||
private static void createNewCloud() {
|
||||
onView(withId(R.id.floating_action_button)) //
|
||||
.perform(click());
|
||||
}
|
||||
|
||||
private static void startLoginProcess() {
|
||||
onView(withId(R.id.createCloudButton)) //
|
||||
.perform(click());
|
||||
}
|
||||
|
||||
/*
|
||||
* private static void loginAuthenticationFailWebdavCloud(SplashActivity activity) {
|
||||
* createNewCloud();
|
||||
* enterCredentials(AUTHENTICATION_FAIL);
|
||||
* startLoginProcess();
|
||||
*
|
||||
* onView(withText(R.string.error_authentication_failed)) //
|
||||
* .inRoot(withDecorView(not(is(activity.getWindow().getDecorView())))) //
|
||||
* .check(matches(isDisplayed()));
|
||||
*
|
||||
* onView(allOf( //
|
||||
* withId(R.id.et_url_port), //
|
||||
* withText(AUTHENTICATION_FAIL.url)));
|
||||
*
|
||||
* onView(allOf( //
|
||||
* withId(R.id.et_user), //
|
||||
* withText(AUTHENTICATION_FAIL.username)));
|
||||
*
|
||||
* onView(allOf( //
|
||||
* withId(R.id.et_password), //
|
||||
* withText(AUTHENTICATION_FAIL.password)));
|
||||
*
|
||||
* pressBack();
|
||||
* }
|
||||
*
|
||||
* private static void loginSelfSignedWebdavCloud() {
|
||||
* createNewCloud();
|
||||
* enterCredentials(SELF_SIGNED_HTTPS);
|
||||
* startLoginProcess();
|
||||
* clickOk();
|
||||
* startLoginProcess();
|
||||
* checkResult(SELF_SIGNED_HTTPS);
|
||||
* }
|
||||
*
|
||||
* private static void loginRedirectToHttpsWebdavCloud() {
|
||||
* createNewCloud();
|
||||
* enterCredentials(REDIRECT_TO_HTTPS);
|
||||
* startLoginProcess();
|
||||
* clickOk();
|
||||
* clickOk();
|
||||
* startLoginProcess();
|
||||
* checkResult(REDIRECT_TO_HTTPS);
|
||||
* }
|
||||
*
|
||||
* private static void loginRedirectToUrlWebdavCloud() {
|
||||
* createNewCloud();
|
||||
* enterCredentials(REDIRECT_TO_URL);
|
||||
* startLoginProcess();
|
||||
* clickOk();
|
||||
* startLoginProcess();
|
||||
* }
|
||||
*/
|
||||
|
||||
private static void enterCredentials(WebdavCloudCredentials webdavCloudCredential) {
|
||||
onView(withId(R.id.urlPortEditText)) //
|
||||
.perform(replaceText(webdavCloudCredential.url));
|
||||
|
||||
onView(withId(R.id.userNameEditText)) //
|
||||
.perform(replaceText(webdavCloudCredential.username));
|
||||
|
||||
onView(withId(R.id.passwordEditText)) //
|
||||
.perform( //
|
||||
replaceText(webdavCloudCredential.password), //
|
||||
closeSoftKeyboard());
|
||||
}
|
||||
|
||||
private static void checkResult(WebdavCloudCredentials webdavCloudCredential) {
|
||||
onView(allOf( //
|
||||
withId(R.id.cloudText), //
|
||||
withText(webdavCloudCredential.displayUrl)));
|
||||
|
||||
onView(allOf( //
|
||||
withId(R.id.cloudSubText), //
|
||||
withText(webdavCloudCredential.username + " • ")));
|
||||
}
|
||||
|
||||
enum WebdavCloudCredentials {
|
||||
GMX("https://webdav.mc.gmx.net/", "webdav.mc.gmx.net", "jraufelder@gmx.de", "mG7!3B3Mx"), //
|
||||
/*
|
||||
* FREENET("https://webmail.freenet.de/webdav", "webmail.freenet.de", "milestone@freenet.de", "rF7!3B3Et")
|
||||
*
|
||||
* , //
|
||||
* /*
|
||||
* AUTHENTICATION_FAIL("https://webdav.mc.gmx.net/", "webdav.mc.gmx.net", "bla@bla.de", "bla"), //
|
||||
* SELF_SIGNED_HTTPS("https://" + localUrl + "/webdav", localUrl + "/webdav", "bla@bla.de", "bla"), //
|
||||
* REDIRECT_TO_HTTPS("http://" + localUrl + "/webdav", localUrl + "/webdav", "bla@bla.de", "bla"), //
|
||||
* REDIRECT_TO_URL("https://" + localUrl + "/bar/baz", localUrl + "/bar/baz", "bla@bla.de", "bla")
|
||||
*/;
|
||||
|
||||
private final String url;
|
||||
private final String displayUrl;
|
||||
private final String username;
|
||||
private final String password;
|
||||
|
||||
WebdavCloudCredentials(String url, String displayUrl, String username, String password) {
|
||||
this.url = url;
|
||||
this.displayUrl = displayUrl;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
static List<WebdavCloudCredentials> notSpecialWebdavClouds() {
|
||||
return Collections.singletonList(GMX/* , FREENET */);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,412 +0,0 @@
|
||||
package org.cryptomator.presentation.ui.activity;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.rule.ActivityTestRule;
|
||||
import androidx.test.uiautomator.UiDevice;
|
||||
import androidx.test.uiautomator.UiSelector;
|
||||
|
||||
import org.cryptomator.domain.CloudType;
|
||||
import org.cryptomator.presentation.CryptomatorApp;
|
||||
import org.cryptomator.presentation.R;
|
||||
import org.cryptomator.presentation.di.component.ApplicationComponent;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.Espresso.pressBack;
|
||||
import static androidx.test.espresso.action.ViewActions.click;
|
||||
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
|
||||
import static androidx.test.espresso.action.ViewActions.replaceText;
|
||||
import static androidx.test.espresso.assertion.ViewAssertions.matches;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withId;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withText;
|
||||
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||
import static org.cryptomator.domain.executor.BackgroundTasks.awaitCompleted;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.DROPBOX;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.GOOGLE_DRIVE;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.LOCAL;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.ONEDRIVE;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.WEBDAV;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.isToastDisplayed;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.removeFolderInCloud;
|
||||
import static org.cryptomator.presentation.ui.TestUtil.waitForIdle;
|
||||
import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.checkEmptyFolderHint;
|
||||
import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.checkFileOrFolderAlreadyExistsErrorMessage;
|
||||
import static org.cryptomator.presentation.ui.activity.BasicNodeOperationsUtil.withRecyclerView;
|
||||
import static org.cryptomator.presentation.ui.activity.FileOperationsTest.grantPermission;
|
||||
import static org.cryptomator.presentation.ui.activity.FileOperationsTest.isPermissionShown;
|
||||
import static org.cryptomator.presentation.ui.activity.FileOperationsTest.openFile;
|
||||
import static org.cryptomator.presentation.ui.activity.FolderOperationsTest.openFolder;
|
||||
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
@RunWith(Parameterized.class)
|
||||
public class VaultsOperationsTest {
|
||||
|
||||
@Rule
|
||||
public final ActivityTestRule<SplashActivity> activityTestRule = new ActivityTestRule<>(SplashActivity.class);
|
||||
|
||||
private final UiDevice device = UiDevice.getInstance(getInstrumentation());
|
||||
private final Context context = InstrumentationRegistry.getTargetContext();
|
||||
|
||||
private final Integer cloudId;
|
||||
|
||||
public VaultsOperationsTest(Integer cloudId, String cloudName) {
|
||||
this.cloudId = cloudId;
|
||||
}
|
||||
|
||||
@Parameterized.Parameters(name = "{1}")
|
||||
public static Iterable<Object[]> data() {
|
||||
return Arrays.asList(new Object[][] {{DROPBOX, "DROPBOX"}, {GOOGLE_DRIVE, "GOOGLE_DRIVE"}, {ONEDRIVE, "ONEDRIVE"}, {WEBDAV, "WEBDAV"}, {LOCAL, "LOCAL"}});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test00CreateNewVaultsLeadsToNewVaults() {
|
||||
ApplicationComponent appComponent = ((CryptomatorApp) activityTestRule.getActivity().getApplication()).getComponent();
|
||||
String path = "0/tempVault/";
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
// Permission problem
|
||||
if (cloudId != LOCAL) {
|
||||
removeFolderInCloud(appComponent, path, CloudType.values()[cloudId]);
|
||||
removeFolderInCloud(appComponent, "0/testVault/", CloudType.values()[cloudId]);
|
||||
removeFolderInCloud(appComponent, "0/testLoggedInVault/", CloudType.values()[cloudId]);
|
||||
}
|
||||
|
||||
onView(withId(R.id.floating_action_button)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.create_new_vault)) //
|
||||
.perform(click());
|
||||
|
||||
createVault(cloudId, appComponent, path);
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
unlockVault("tempVault", cloudId);
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
checkEmptyFolderHint();
|
||||
|
||||
pressBack();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test01RenameLoggedInVaultToAlreadyExistingNameLeadsToNothingChanged() {
|
||||
String vaultName = "tempVault";
|
||||
|
||||
renameVault(cloudId, vaultName);
|
||||
|
||||
checkFileOrFolderAlreadyExistsErrorMessage(vaultName);
|
||||
|
||||
onView(withId(android.R.id.button2)) //
|
||||
.perform(click());
|
||||
|
||||
checkVault(cloudId, vaultName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test02ChangeLoggedInVaultPasswordLeadsToNewPassword() {
|
||||
String oldPassword = "tempVault";
|
||||
String newPassword = "foo";
|
||||
|
||||
changePassword(cloudId, oldPassword, newPassword);
|
||||
|
||||
isToastDisplayed(context.getString(R.string.screen_vault_list_change_password_successful), activityTestRule);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test03RenameLoggedInVaultToNewNameLeadsToNewName() {
|
||||
String vaultName = "testLoggedInVault";
|
||||
|
||||
renameVault(cloudId, vaultName);
|
||||
|
||||
checkVault(cloudId, vaultName);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test04RenameLoggedOutVaultToAlreadyExistingNameLeadsToNothingChanged() {
|
||||
String vaultName = "testLoggedInVault";
|
||||
|
||||
renameVault(cloudId, vaultName);
|
||||
|
||||
checkFileOrFolderAlreadyExistsErrorMessage(vaultName);
|
||||
|
||||
onView(withId(android.R.id.button2)) //
|
||||
.perform(click());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test05RenameLoggedOutVaultToNewNameLeadsToNewName() {
|
||||
String vaultName = "testVault";
|
||||
|
||||
renameVault(cloudId, vaultName);
|
||||
|
||||
checkVault(cloudId, vaultName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test06ChangeLoggedOutVaultPasswordLeadsToNewPassword() {
|
||||
String oldPassword = "foo";
|
||||
String newPassword = "testVault";
|
||||
|
||||
changePassword(cloudId, oldPassword, newPassword);
|
||||
|
||||
isToastDisplayed(context.getString(R.string.screen_vault_list_change_password_successful), activityTestRule);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test07DeleteVaultsLeadsToDeletedVaults() {
|
||||
waitForIdle(device);
|
||||
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(cloudId, R.id.settings)) //
|
||||
.perform(click());
|
||||
|
||||
waitForIdle(device);
|
||||
|
||||
onView(withId(R.id.delete_vault)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(android.R.id.button1)) //
|
||||
.perform(click());
|
||||
|
||||
onView(withId(R.id.tv_creation_hint));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test08addExistingVaultsLeadsToAddedVaults() {
|
||||
waitForIdle(device);
|
||||
|
||||
onView(withId(R.id.floating_action_button)) //
|
||||
.perform(click());
|
||||
|
||||
waitForIdle(device);
|
||||
|
||||
onView(withId(R.id.add_existing_vault)) //
|
||||
.perform(click());
|
||||
|
||||
openVault(cloudId);
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
unlockVault("testVault", cloudId);
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
checkEmptyFolderHint();
|
||||
|
||||
pressBack();
|
||||
}
|
||||
|
||||
private void renameVault(int position, String vaultName) {
|
||||
awaitCompleted();
|
||||
|
||||
waitForIdle(device);
|
||||
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(position, R.id.settings)) //
|
||||
.perform(click());
|
||||
|
||||
waitForIdle(device);
|
||||
|
||||
onView(withId(R.id.et_rename)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
waitForIdle(device);
|
||||
|
||||
onView(withId(R.id.et_rename)) //
|
||||
.perform(replaceText("tempVault"), closeSoftKeyboard());
|
||||
|
||||
onView(withId(R.id.et_rename)) //
|
||||
.perform(replaceText(vaultName), closeSoftKeyboard());
|
||||
|
||||
onView(withId(android.R.id.button1)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
private void createVault(int vaultPosition, ApplicationComponent appComponent, String path) {
|
||||
awaitCompleted();
|
||||
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(vaultPosition, R.id.cloud)) //
|
||||
.perform(click());
|
||||
|
||||
String vaultnameAndPassword = "tempVault";
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
switch (vaultPosition) {
|
||||
case WEBDAV:
|
||||
awaitCompleted();
|
||||
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(0, R.id.cloudText)) //
|
||||
.perform(click());
|
||||
break;
|
||||
case LOCAL:
|
||||
awaitCompleted();
|
||||
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(0, R.id.cloudText)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
isPermissionShown(device);
|
||||
grantPermission(device);
|
||||
|
||||
removeFolderInCloud(appComponent, path, CloudType.LOCAL);
|
||||
removeFolderInCloud(appComponent, "0/testVault/", CloudType.LOCAL);
|
||||
removeFolderInCloud(appComponent, "0/testLoggedInVault/", CloudType.LOCAL);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.vaultNameEditText)) //
|
||||
.perform(replaceText(vaultnameAndPassword), closeSoftKeyboard());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.createVaultButton)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
openFolder(0);
|
||||
|
||||
onView(withId(R.id.chooseLocationButton)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.passwordEditText)) //
|
||||
.perform(replaceText(vaultnameAndPassword));
|
||||
|
||||
onView(withId(R.id.passwordRetypedEditText)) //
|
||||
.perform(replaceText(vaultnameAndPassword), closeSoftKeyboard());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.createVaultButton)) //
|
||||
.perform(click());
|
||||
}
|
||||
|
||||
private void openVault(int vaultPosition) {
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(vaultPosition, R.id.cloud)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
switch (vaultPosition) {
|
||||
case WEBDAV:
|
||||
awaitCompleted();
|
||||
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(0, R.id.cloudText)) //
|
||||
.perform(click());
|
||||
break;
|
||||
case LOCAL:
|
||||
awaitCompleted();
|
||||
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(0, R.id.cloudText)) //
|
||||
.perform(click());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
openFolder(0);
|
||||
awaitCompleted();
|
||||
|
||||
openFolder(0);
|
||||
awaitCompleted();
|
||||
|
||||
openFile(1);
|
||||
}
|
||||
|
||||
private void unlockVault(String vaultPassword, int vaultPosition) {
|
||||
waitForIdle(device);
|
||||
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(vaultPosition, R.id.vaultName)) //
|
||||
.perform(click());
|
||||
|
||||
device //
|
||||
.findObject(new UiSelector().text("Password")) //
|
||||
.waitForExists(30000L);
|
||||
|
||||
onView(withId(R.id.et_password)) //
|
||||
.perform(replaceText(vaultPassword), closeSoftKeyboard());
|
||||
onView(withId(android.R.id.button1)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
private void changePassword(int position, String oldPassword, String newPassword) {
|
||||
awaitCompleted();
|
||||
|
||||
waitForIdle(device);
|
||||
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(position, R.id.settings)) //
|
||||
.perform(click());
|
||||
|
||||
waitForIdle(device);
|
||||
|
||||
onView(withId(R.id.change_password)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
|
||||
onView(withId(R.id.et_old_password)) //
|
||||
.perform(replaceText(oldPassword));
|
||||
|
||||
onView(withId(R.id.et_new_password)) //
|
||||
.perform(replaceText(newPassword));
|
||||
|
||||
onView(withId(R.id.et_new_retype_password)) //
|
||||
.perform(replaceText(newPassword), closeSoftKeyboard());
|
||||
|
||||
onView(withId(android.R.id.button1)) //
|
||||
.perform(click());
|
||||
|
||||
awaitCompleted();
|
||||
}
|
||||
|
||||
private void checkVault(int position, String name) {
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(position, R.id.vaultName)) //
|
||||
.check(matches(withText(name)));
|
||||
|
||||
onView(withRecyclerView(R.id.recyclerView) //
|
||||
.atPositionOnView(position, R.id.vaultPath)) //
|
||||
.check(matches(withText("/0/" + name)));
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package org.cryptomator.presentation.ui.activity.suite;
|
||||
|
||||
import org.junit.runner.notification.Failure;
|
||||
import org.junit.runner.notification.RunListener;
|
||||
import org.junit.runner.notification.RunNotifier;
|
||||
|
||||
class FailureListener extends RunListener {
|
||||
|
||||
private final RunNotifier runNotifier;
|
||||
|
||||
FailureListener(RunNotifier runNotifier) {
|
||||
super();
|
||||
this.runNotifier = runNotifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testFailure(Failure failure) throws Exception {
|
||||
super.testFailure(failure);
|
||||
this.runNotifier.pleaseStop();
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package org.cryptomator.presentation.ui.activity.suite;
|
||||
|
||||
import org.junit.runner.notification.RunNotifier;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.model.InitializationError;
|
||||
|
||||
public class StopOnFailureSuite extends Suite {
|
||||
|
||||
public StopOnFailureSuite(Class<?> klass, Class<?>[] suiteClasses) throws InitializationError {
|
||||
super(klass, suiteClasses);
|
||||
}
|
||||
|
||||
public StopOnFailureSuite(Class<?> klass) throws InitializationError {
|
||||
super(klass, klass.getAnnotation(Suite.SuiteClasses.class).value());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(RunNotifier runNotifier) {
|
||||
runNotifier.addListener(new FailureListener(runNotifier));
|
||||
super.run(runNotifier);
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package org.cryptomator.presentation.ui.activity.suite;
|
||||
|
||||
import org.cryptomator.presentation.ui.activity.CloudsOperationsTest;
|
||||
import org.cryptomator.presentation.ui.activity.FileOperationsTest;
|
||||
import org.cryptomator.presentation.ui.activity.FolderOperationsTest;
|
||||
import org.cryptomator.presentation.ui.activity.VaultsOperationsTest;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
|
||||
@Ignore
|
||||
@RunWith(StopOnFailureSuite.class)
|
||||
@Suite.SuiteClasses({ //
|
||||
CloudsOperationsTest.class, //
|
||||
VaultsOperationsTest.class, //
|
||||
FolderOperationsTest.class, //
|
||||
FileOperationsTest.class //
|
||||
})
|
||||
public class UiTestSuite {
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user