diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6ba265a284592e3672280c4bdf7c0aa14a25109d..b71b2cbc5981f0b48c4089899005654eda611351 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,6 +1,7 @@
image: "registry.gitlab.e.foundation:5000/e/apps/docker-android-apps-cicd:latest"
stages:
+- test
- build
before_script:
@@ -9,15 +10,32 @@ before_script:
- export GRADLE_USER_HOME=$(pwd)/.gradle
- chmod +x ./gradlew
+
cache:
key: ${CI_PROJECT_ID}
paths:
- .gradle/
+
+test:
+ allow_failure: true
+ stage: test
+ script:
+ - ls /usr/lib/jvm/
+ - ./gradlew test -Dorg.gradle.java.home=/usr/lib/jvm/java-8-openjdk-amd64 -PtestAccountName="$testAccountName" -PtestAccountPwd="$testAccountPwd" -PtestServerUrl="$testServerUrl"
+ artifacts:
+ when: always
+ paths:
+ - app/build/test-results/*/TEST-*.xml
+ - app/build/reports/tests/*
+ reports:
+ junit: app/build/test-results/*/TEST-*.xml
+
+
build:
stage: build
script:
- - ./gradlew build
+ - ./gradlew build -x test
artifacts:
paths:
- app/build/outputs/apk/
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 73f2520ea0453ae3c2a7d931f8596f3124c8d27f..0000000000000000000000000000000000000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 5b312b6a558f631c50b1676e97ba4c3fdce24957..c93eb509511055cacde6495a8b826e2845631a45 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -9,6 +9,18 @@ def buildTime() {
return df.format(new Date())
}
+def getTestProp(String propName) {
+ def result = ""
+ if(project.hasProperty(propName)){
+ result =project.property(propName).toString()
+ }else if(project.rootProject.file('local.properties').exists()){
+ Properties properties = new Properties()
+ properties.load(project.rootProject.file('local.properties').newReader())
+ result = properties.getProperty(propName)
+ }
+ return result
+}
+
android {
compileSdkVersion 26
@@ -19,7 +31,9 @@ android {
//versionName "1.0"
versionName "beta-${versionMajor}-build-o-${buildTime()}"
setProperty("archivesBaseName", "$applicationId.$versionName")
-
+ buildConfigField "String", "testAccountName", "\""+getTestProp("testAccountName")+"\""
+ buildConfigField "String", "testAccountPWd", "\""+getTestProp("testAccountPwd")+"\""
+ buildConfigField "String", "testServerUrl", "\""+getTestProp("testServerUrl")+"\""
}
buildTypes {
release {
@@ -34,19 +48,37 @@ android {
testOptions {
- unitTests.returnDefaultValues = true
+ unitTests {
+ returnDefaultValues = true
+ //includeAndroidResources = true
+ }
}
+
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:26.1.0'
- testImplementation 'junit:junit:4.12'
+
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2'
androidTestImplementation 'com.android.support:support-annotations:27.1.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
api 'com.android.support:support-annotations:27.1.1'
api project(':NextcloudLib')
+
+ //start to add lib for test - 1/4/21
+ //@TODO: add junit runner as lib for testImplementation
+
+ testImplementation 'com.android.support.test:runner:1.0.2'
+ testImplementation 'com.android.support.test:rules:1.0.2'
+ testImplementation 'junit:junit:4.12'
+ //testImplementation 'org.robolectric:robolectric:4.4' //need AndroidX
+ testImplementation "org.robolectric:robolectric:3.8"
+ testImplementation('org.mockito:mockito-inline:3.4.0')
+
+ //testImplementation Libs.AndroidX.Test.archCoreTesting //TODO: replace by not android X version
+ //implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
+ androidTestImplementation 'junit:junit:4.12'
}
diff --git a/app/src/androidTest/java/foundation/e/drive/ExampleInstrumentedTest.java b/app/src/androidTest/java/foundation/e/drive/ExampleInstrumentedTest.java
deleted file mode 100644
index e6c481cdcd194c3e4b10af9498f7f5325993bf15..0000000000000000000000000000000000000000
--- a/app/src/androidTest/java/foundation/e/drive/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright © Vincent Bourgmayer (/e/ foundation).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Public License v3.0
- * which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/gpl.html
- */
-
-
-package foundation.e.drive;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() throws Exception {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
-
- assertEquals("foundation.e.drive", appContext.getPackageName());
- }
-}
diff --git a/app/src/androidTest/java/foundation/e/drive/services/ObserverServiceInstrumentedTest.java b/app/src/androidTest/java/foundation/e/drive/services/ObserverServiceInstrumentedTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..bd5fe22cd23116c10c5b0b339b4a18eb8ba736dc
--- /dev/null
+++ b/app/src/androidTest/java/foundation/e/drive/services/ObserverServiceInstrumentedTest.java
@@ -0,0 +1,100 @@
+package foundation.e.drive.services;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Environment;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ServiceTestRule;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.concurrent.TimeoutException;
+
+import static android.support.test.InstrumentationRegistry.getContext;
+import static org.junit.Assert.*;
+
+
+
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ObserverServiceInstrumentedTest {
+ private final static String NEW_SMALL_FILE_PATH = Environment.getExternalStorageDirectory() + File.separator + Environment.DIRECTORY_DOCUMENTS+File.separator+"test-small-file.txt";
+ private final static String ACCOUNT_NAME= "";
+ private final static String ACCOUNT_PASS="";
+ private final static String ACCOUNT_TYPE="";
+
+
+ @Rule
+ public final ServiceTestRule mServiceRule = new ServiceTestRule();
+
+
+ @Before
+ public void RegisterAccount() throws Exception {
+ final Account account = new Account(ACCOUNT_NAME, ACCOUNT_TYPE);
+ AccountManager.get(getContext()).addAccountExplicitly(account, ACCOUNT_PASS, null);
+
+ }
+
+
+ /**
+ * Souldn't it be more for a unit test ?
+ * @throws IOException
+ */
+ @Before
+ public void createLocalSmallFile() throws IOException {
+
+ File file = new File(NEW_SMALL_FILE_PATH);
+ file.createNewFile();
+ String content = "this a very small content";
+//write the bytes in file
+ if(file.exists())
+ {
+ OutputStream fo = new FileOutputStream(file);
+ fo.write(content.getBytes());
+ fo.close();
+ System.out.println("file created: "+file);
+ }
+ }
+
+
+ @After
+ public void deleteLocalSmallFile(){
+ File file = new File(NEW_SMALL_FILE_PATH);
+ //deleting the file
+ file.delete();
+ }
+
+
+ @Test
+ public void testWithStartedService() throws TimeoutException {
+ mServiceRule.startService(
+ new Intent(InstrumentationRegistry.getTargetContext(), ObserverService.class));
+ //do something
+ }
+
+ @Test
+ public void useAppContext() throws Exception {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+
+ assertEquals("foundation.e.drive", appContext.getPackageName());
+ }
+}
diff --git a/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java b/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java
index 88276a6b9703b773b4bdaf40e115b3b11e4e59e0..515ce35f4ab8a548244d5f63d48b85f740e1561b 100644
--- a/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java
+++ b/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java
@@ -11,6 +11,7 @@ package foundation.e.drive.operations;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
+import android.support.annotation.VisibleForTesting;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.UserInfo;
@@ -217,7 +218,8 @@ public class UploadFileOperation extends RemoteOperation implements ComparableOp
* @param client OwnCloudClient
* @return RemoteOperationResult
*/
- private RemoteOperationResult checkAvailableSpace(OwnCloudClient client, long fileSize){
+ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+ public RemoteOperationResult checkAvailableSpace(OwnCloudClient client, long fileSize){
GetRemoteUserInfoOperation getRemoteUserInfoOperation = new GetRemoteUserInfoOperation();
RemoteOperationResult ocsResult = getRemoteUserInfoOperation.execute(client);
if(ocsResult.isSuccess() && ocsResult.getData() != null){
diff --git a/app/src/main/java/foundation/e/drive/utils/CommonUtils.java b/app/src/main/java/foundation/e/drive/utils/CommonUtils.java
index 2d1c16e2075583f573ec17e3d5845d66938b3a93..b6de97e44b0d2ea228d2db038c3e039357f6de12 100644
--- a/app/src/main/java/foundation/e/drive/utils/CommonUtils.java
+++ b/app/src/main/java/foundation/e/drive/utils/CommonUtils.java
@@ -17,6 +17,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.media.MediaScannerConnection;
import android.net.ConnectivityManager;
+import android.net.Network;
import android.net.NetworkInfo;
import android.net.Uri;
import android.support.annotation.NonNull;
@@ -54,7 +55,7 @@ public abstract class CommonUtils {
public static void setServiceUnCaughtExceptionHandler(Service service) {
Thread.UncaughtExceptionHandler defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
- if (defaultUEH.getClass().getSimpleName().equals(ServiceExceptionHandler.class.getSimpleName())) {
+ if (defaultUEH != null && ServiceExceptionHandler.class.getSimpleName().equals(defaultUEH.getClass().getSimpleName())) {
Log.d("ObserverService", "ServiceExceptionHandler already set!");
((ServiceExceptionHandler) defaultUEH).setService(service);
} else {
@@ -206,10 +207,10 @@ public abstract class CommonUtils {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
- if (ni.getTypeName().equalsIgnoreCase("WIFI"))
+ if (ni.getType()== ConnectivityManager.TYPE_WIFI) // Replaced the ni.getTypeName by ni.getType to make the test from ObserverServiceTest to work. But looks a better solution in all case
if (ni.isConnected())
haveConnectedWifi = true;
- if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
+ if (ni.getType()== ConnectivityManager.TYPE_MOBILE)
if (ni.isConnected())
haveConnectedMobile = true;
}
diff --git a/app/src/test/java/foundation/e/drive/Test/CommonUtilsUnitTest.java b/app/src/test/java/foundation/e/drive/Test/CommonUtilsUnitTest.java
deleted file mode 100644
index e76ac1e6d2451257e97a8e5a6439ba0abd8a2203..0000000000000000000000000000000000000000
--- a/app/src/test/java/foundation/e/drive/Test/CommonUtilsUnitTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright © Vincent Bourgmayer (/e/ foundation).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Public License v3.0
- * which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/gpl.html
- */
-package foundation.e.drive.Test;
-import android.accounts.Account;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * @author Vincent Bourgmayer
- * raw mock will be replace ASAP to use mockito or other similar framework
- */
-public class CommonUtilsUnitTest {
-
- @Test
- public void testIsThisSyncAllowed(){
-
- boolean isMediaType = true; //sfs is media element
-
- MockAccount account = new MockAccount("allowed", "allowed"); //Both type sync are allowed
-
- Assert.assertNotNull("Assert account not null", account);
-
- Assert.assertTrue(isThisSyncAllowed(account, isMediaType));
-
- account = new MockAccount("allowed", "not allowed"); //Only Media sync is enabled
- Assert.assertTrue(isThisSyncAllowed(account, isMediaType));
-
- account = new MockAccount("not allowed", "allowed"); //Only settings sync is enabled
- Assert.assertFalse(isThisSyncAllowed(account, isMediaType));
-
- account = new MockAccount("not allowed", "not allowed"); //no sync is enabled
- Assert.assertFalse(isThisSyncAllowed(account, isMediaType));
-
- isMediaType = false;
- Assert.assertFalse(isThisSyncAllowed(account, isMediaType));
-
- account = new MockAccount("allowed", "not allowed"); //Only Media sync is enabled
- Assert.assertFalse(isThisSyncAllowed(account, isMediaType));
-
- account = new MockAccount("not allowed", "allowed"); //Only settings sync is enabled
- Assert.assertTrue(isThisSyncAllowed(account, isMediaType));
-
- account = new MockAccount("allowed", "allowed"); //no sync is enabled
- Assert.assertTrue(isThisSyncAllowed(account, isMediaType));
-
- }
-
-
- static boolean isThisSyncAllowed(MockAccount account, boolean syncedFileStateIsMedia){
- return ( syncedFileStateIsMedia && mockedIsMediaSyncEnabled(account) )
- || ( !syncedFileStateIsMedia && mockedIsSettingsSyncEnabled(account) ) ;
- }
-
- //@mock tmp
- static boolean mockedIsMediaSyncEnabled(MockAccount account){
- return account.mockName.equals("allowed");
- }
-
- //@mock tmp
- static boolean mockedIsSettingsSyncEnabled(MockAccount account){
- return account.mockType.equals("allowed");
- }
-
-
- /**
- * Tmp mock class
- */
- public class MockAccount extends Account{
-
- String mockName;
- String mockType;
- MockAccount(String name, String type) {
- super(name, type);
- this.mockName = name;
- this.mockType = type;
- }
- }
-}
diff --git a/app/src/test/java/foundation/e/drive/Test/FileFilterTest/CrashlogFileFilterTest.java b/app/src/test/java/foundation/e/drive/Test/FileFilterTest/CrashlogFileFilterTest.java
deleted file mode 100644
index 69950012771be37419c515ddc87f2d6a6a45ab7a..0000000000000000000000000000000000000000
--- a/app/src/test/java/foundation/e/drive/Test/FileFilterTest/CrashlogFileFilterTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package foundation.e.drive.Test.FileFilterTest;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class CrashlogFileFilterTest {
-
- private String mockFileName(String target, String prefix, String extension){
- return prefix+target+extension;
- }
-
- private String extractTimestamp(String fileName, String prefix, String extension){
- return fileName.substring(prefix.length(), (fileName.length() - extension.length()));
- }
-
- @Test
- public void extractTimeStampFromFileNameTest(){
- String prefix = "edrive-";
- String extension = ".log";
- String target = "";
- //Case 1 Empty Target
- String base = mockFileName(target, prefix, extension);
- Assert.assertEquals("Base length is incorrect", prefix.length()+extension.length(), base.length());
-
- String fileTimestamp = extractTimestamp(base, prefix, extension);
- Assert.assertEquals("result is not empty String", "", fileTimestamp);
-
- //Case 2: Prefix is empty
- prefix = "";
- target = "1234";
- base = mockFileName(target, prefix, extension);
- Assert.assertEquals("Base length is incorrect", prefix.length()+target.length()+extension.length(), base.length());
-
- fileTimestamp = extractTimestamp(base, prefix, extension);
- Assert.assertEquals("result is not empty String", target, fileTimestamp);
-
- //Case 3: extension is empty
-
- prefix = "edrive-";
- extension = "";
-
- base = mockFileName(target, prefix, extension);
- Assert.assertEquals("Base length is incorrect", prefix.length()+target.length(), base.length());
-
- fileTimestamp = extractTimestamp(base, prefix, extension);
- Assert.assertEquals("result is not empty String", target, fileTimestamp);
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/foundation/e/drive/Test/FileFilterTest/FileFilterUnitTest.java b/app/src/test/java/foundation/e/drive/Test/FileFilterTest/FileFilterUnitTest.java
deleted file mode 100644
index 6d3d3051ada390ca6b943440546fa6df25cebdb2..0000000000000000000000000000000000000000
--- a/app/src/test/java/foundation/e/drive/Test/FileFilterTest/FileFilterUnitTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright © Vincent Bourgmayer (/e/ foundation).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Public License v3.0
- * which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/gpl.html
- */
-
-
-package foundation.e.drive.Test.FileFilterTest;
-
-import junit.framework.Assert;
-
-import org.junit.Test;
-
-import foundation.e.drive.utils.AppConstants;
-/**
- * @author Vincent Bourgmayer
- */
-public class FileFilterUnitTest {
-
- @Test
- public void SettingsFileFilterUnitTest(){
- //Directory situation
- Assert.assertFalse(mockSettingFileFilterAcceptMethod("", false));
- Assert.assertFalse(mockSettingFileFilterAcceptMethod("", true));
- Assert.assertFalse(mockSettingFileFilterAcceptMethod("settings_foo.xml", false));
- Assert.assertFalse(mockSettingFileFilterAcceptMethod(AppConstants.APPLICATIONS_LIST_FILE_NAME, false));
- Assert.assertFalse(mockSettingFileFilterAcceptMethod("settings_", true));
- Assert.assertFalse(mockSettingFileFilterAcceptMethod(".xml", true));
- Assert.assertFalse(mockSettingFileFilterAcceptMethod("settings_"+AppConstants.APPLICATIONS_LIST_FILE_NAME, true));
-
-
- Assert.assertTrue(mockSettingFileFilterAcceptMethod("settings_.xml", true));
- Assert.assertTrue(mockSettingFileFilterAcceptMethod("settings_foo.xml", true));
- Assert.assertTrue(mockSettingFileFilterAcceptMethod(AppConstants.APPLICATIONS_LIST_FILE_NAME, true));
- }
-
- private boolean mockSettingFileFilterAcceptMethod(String name, boolean isFile){
- return ( isFile &&
- ( ( name.startsWith("settings_") && name.endsWith(".xml") )
- || name.equals( AppConstants.APPLICATIONS_LIST_FILE_NAME ) ) );
- }
-}
diff --git a/app/src/test/java/foundation/e/drive/Test/MD5Test.java b/app/src/test/java/foundation/e/drive/Test/MD5Test.java
deleted file mode 100644
index c68da4cf5a0a2ccd32e6696102c0668d97eaa5aa..0000000000000000000000000000000000000000
--- a/app/src/test/java/foundation/e/drive/Test/MD5Test.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package foundation.e.drive.Test;
-
-
-/*
- * Copyright (C) 2012 The CyanogenMod Project
- *
- * * Licensed under the GNU GPLv2 license
- *
- * The text of the license can be found in the LICENSE file
- * or at https://www.gnu.org/licenses/gpl-2.0.txt
- */
-
- import android.text.TextUtils;
- import android.util.Log;
-
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStream;
- import java.math.BigInteger;
- import java.security.MessageDigest;
- import java.security.NoSuchAlgorithmException;
-
-public class MD5Test {
- private static final String TAG = "MD5";
-
- public static boolean checkMD5(String md5, File updateFile) {
- if (TextUtils.isEmpty(md5) || updateFile == null) {
- Log.e(TAG, "MD5 string empty or updateFile null");
- return false;
- }
-
- String calculatedDigest = calculateMD5(updateFile);
- if (calculatedDigest == null) {
- Log.e(TAG, "calculatedDigest null");
- return false;
- }
-
- Log.v(TAG, "Calculated digest: " + calculatedDigest);
- Log.v(TAG, "Provided digest: " + md5);
-
- return calculatedDigest.equalsIgnoreCase(md5);
- }
-
- public static String calculateMD5(File updateFile) {
- MessageDigest digest;
- try {
- digest = MessageDigest.getInstance("MD5");
- } catch (NoSuchAlgorithmException e) {
- Log.e(TAG, "Exception while getting digest", e);
- return null;
- }
-
- InputStream is;
- try {
- is = new FileInputStream(updateFile);
- } catch (FileNotFoundException e) {
- Log.e(TAG, "Exception while getting FileInputStream", e);
- return null;
- }
-
- byte[] buffer = new byte[8192];
- int read;
- try {
- while ((read = is.read(buffer)) > 0) {
- digest.update(buffer, 0, read);
- }
- byte[] md5sum = digest.digest();
- BigInteger bigInt = new BigInteger(1, md5sum);
- String output = bigInt.toString(16);
- // Fill to 32 chars
- output = String.format("%32s", output).replace(' ', '0');
- return output;
- } catch (IOException e) {
- throw new RuntimeException("Unable to process file for MD5", e);
- } finally {
- try {
- is.close();
- } catch (IOException e) {
- Log.e(TAG, "Exception on closing MD5 input stream", e);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/foundation/e/drive/Test/ObserverServiceUnitTest.java b/app/src/test/java/foundation/e/drive/Test/ObserverServiceUnitTest.java
deleted file mode 100644
index e96d74031bd3410806a2e4e8f1e3a33d518dd5cf..0000000000000000000000000000000000000000
--- a/app/src/test/java/foundation/e/drive/Test/ObserverServiceUnitTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright © Vincent Bourgmayer (/e/ foundation).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Public License v3.0
- * which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/gpl.html
- */
-package foundation.e.drive.Test;
-
-import org.junit.Assert;
-import org.junit.Test;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * @author Vincent Bourgmayer
- */
-
-public class ObserverServiceUnitTest {
-
- public File[] mockCachedFile(){
- File[] mockFile= new File[5];
- for(int i = 0; i < 5; ++i){
- mockFile[i] = new File("/emulated/storage/0/android/data/toto"+i+".jpg");
- }
- return mockFile;
- }
-
- public List mockUsedFilePath (){
- List stringList = new ArrayList<>();
- System.out.println("Stringset:"+( (stringList == null)? false: true) );
- boolean a1 = stringList.add( new String("/emulated/storage/0/DCIM/Camera/toto1.jpg") );
- boolean a2 = stringList.add( new String("/emulated/storage/0/DCIM/Camera/toto2.jpg") );
- //boolean a3 = stringSet.add( new String("/emulated/storage/0/DCIM/Camera/toto4.jpg") );
- Assert.assertNotNull(stringList);
- return stringList;
- }
-
- @Test
- public void handleCachedFile(){
- //Load subfiles into external cache file
- //Mock this
- File[] fileArray = mockCachedFile();
-
- Assert.assertNotNull(fileArray);
- //Mock this;
- List usedFilePath = mockUsedFilePath();
-
- Assert.assertNotNull(usedFilePath);
- boolean toRemove = true;
- for(int i =0; i < fileArray.length; ++i){
- toRemove = true;
- //System.out.println( fileArray[i] );
- for(String filePath : usedFilePath){
-
- if(filePath.endsWith(fileArray[i].getName())){
- System.out.println("TRUE");
- toRemove = false;
- }else
- System.out.println("FALSE");
- }
- if(toRemove){
- System.out.println("Deletion of file: "+fileArray[i].getName() );
- }
- }
- }
-}
diff --git a/app/src/test/java/foundation/e/drive/Test/SyncedFolderUnitTest.java b/app/src/test/java/foundation/e/drive/Test/SyncedFolderUnitTest.java
deleted file mode 100644
index d56228ec6f68ef258d8f590c83b5a38d0104a7ee..0000000000000000000000000000000000000000
--- a/app/src/test/java/foundation/e/drive/Test/SyncedFolderUnitTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright © Vincent Bourgmayer (/e/ foundation).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the GNU Public License v3.0
- * which accompanies this distribution, and is available at
- * http://www.gnu.org/licenses/gpl.html
- */
-package foundation.e.drive.Test;
-
-import junit.framework.Assert;
-
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.List;
-
-import foundation.e.drive.models.SyncedFolder;
-
-import static foundation.e.drive.utils.AppConstants.MEDIA_SYNCABLE_CATEGORIES;
-
-/**
- * @author Vincent Bourgmayer
- */
-
-public class SyncedFolderUnitTest {
-
- @Test
- public void childCreationTest(){
- SyncedFolder parent = new SyncedFolder("dummy", "/storage/emulated/0/dummy/", "/dummy/", true, true, true, true);
- Assert.assertNotNull(parent);
- parent.setId(6);
- parent.setLastModified(123456789);
-
- Assert.assertEquals("dummy", parent.getLibelle() );
-
- SyncedFolder child = new SyncedFolder(parent, "sub_dummy/", 234678965, "");
- Assert.assertNotNull("child is null", child);
- Assert.assertEquals("LocalPath isn't valid", "/storage/emulated/0/dummy/sub_dummy/", child.getLocalFolder());
- Assert.assertEquals("remotePath isn't valid", "/dummy/sub_dummy/", child.getRemoteFolder() );
- Assert.assertTrue("lastModified aren't different", child.getLastModified() != parent.getLastModified() );
- Assert.assertEquals("child libelle isn't valid", parent.getLibelle(), child.getLibelle() );
- Assert.assertTrue("Id are the same", parent.getId() != child.getId() );
- }
-
- @Test
- public void testArrayToList(){
- List arrays = Arrays.asList(MEDIA_SYNCABLE_CATEGORIES);
-
- Assert.assertEquals(MEDIA_SYNCABLE_CATEGORIES.length, arrays.size());
-
- }
-}
diff --git a/app/src/test/java/foundation/e/drive/Test/doTest.java b/app/src/test/java/foundation/e/drive/Test/doTest.java
deleted file mode 100644
index b1aa1589e3df6a2f29b37020df0b30bcc7ca6c50..0000000000000000000000000000000000000000
--- a/app/src/test/java/foundation/e/drive/Test/doTest.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package foundation.e.drive.Test;
-
-public class doTest {
-}
diff --git a/app/src/test/java/foundation/e/drive/Test/mockObject/mockContext.java b/app/src/test/java/foundation/e/drive/Test/mockObject/mockContext.java
deleted file mode 100644
index 9e782f6c009a1f553e48588520303f9923a815c6..0000000000000000000000000000000000000000
--- a/app/src/test/java/foundation/e/drive/Test/mockObject/mockContext.java
+++ /dev/null
@@ -1,565 +0,0 @@
-package foundation.e.drive.Test.mockObject;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.AssetManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.database.DatabaseErrorHandler;
-import android.database.sqlite.SQLiteDatabase;
-import android.graphics.Bitmap;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.UserHandle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.view.Display;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-public class mockContext extends Context{
-
- public mockContext(){
-
- }
- @Override
- public AssetManager getAssets() {
- return null;
- }
-
- @Override
- public Resources getResources() {
- return null;
- }
-
- @Override
- public PackageManager getPackageManager() {
- return null;
- }
-
- @Override
- public ContentResolver getContentResolver() {
- return null;
- }
-
- @Override
- public Looper getMainLooper() {
- return null;
- }
-
- @Override
- public Context getApplicationContext() {
- return null;
- }
-
- @Override
- public void setTheme(int resid) {
-
- }
-
- @Override
- public Resources.Theme getTheme() {
- return null;
- }
-
- @Override
- public ClassLoader getClassLoader() {
- return null;
- }
-
- @Override
- public String getPackageName() {
- return null;
- }
-
- @Override
- public ApplicationInfo getApplicationInfo() {
- return null;
- }
-
- @Override
- public String getPackageResourcePath() {
- return null;
- }
-
- @Override
- public String getPackageCodePath() {
- return null;
- }
-
- @Override
- public SharedPreferences getSharedPreferences(String name, int mode) {
- return null;
- }
-
- @Override
- public boolean moveSharedPreferencesFrom(Context sourceContext, String name) {
- return false;
- }
-
- @Override
- public boolean deleteSharedPreferences(String name) {
- return false;
- }
-
- @Override
- public FileInputStream openFileInput(String name) throws FileNotFoundException {
- return null;
- }
-
- @Override
- public FileOutputStream openFileOutput(String name, int mode) throws FileNotFoundException {
- return null;
- }
-
- @Override
- public boolean deleteFile(String name) {
- return false;
- }
-
- @Override
- public File getFileStreamPath(String name) {
- return null;
- }
-
- @Override
- public File getDataDir() {
- return null;
- }
-
- @Override
- public File getFilesDir() {
- return null;
- }
-
- @Override
- public File getNoBackupFilesDir() {
- return null;
- }
-
- @Nullable
- @Override
- public File getExternalFilesDir(@Nullable String type) {
- return null;
- }
-
- @Override
- public File[] getExternalFilesDirs(String type) {
- return new File[0];
- }
-
- @Override
- public File getObbDir() {
- return null;
- }
-
- @Override
- public File[] getObbDirs() {
- return new File[0];
- }
-
- @Override
- public File getCacheDir() {
- return null;
- }
-
- @Override
- public File getCodeCacheDir() {
- return null;
- }
-
- @Nullable
- @Override
- public File getExternalCacheDir() {
- return null;
- }
-
- @Override
- public File[] getExternalCacheDirs() {
- return new File[0];
- }
-
- @Override
- public File[] getExternalMediaDirs() {
- return new File[0];
- }
-
- @Override
- public String[] fileList() {
- return new String[0];
- }
-
- @Override
- public File getDir(String name, int mode) {
- return null;
- }
-
- @Override
- public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) {
- return null;
- }
-
- @Override
- public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, @Nullable DatabaseErrorHandler errorHandler) {
- return null;
- }
-
- @Override
- public boolean moveDatabaseFrom(Context sourceContext, String name) {
- return false;
- }
-
- @Override
- public boolean deleteDatabase(String name) {
- return false;
- }
-
- @Override
- public File getDatabasePath(String name) {
- return null;
- }
-
- @Override
- public String[] databaseList() {
- return new String[0];
- }
-
- @Override
- public Drawable getWallpaper() {
- return null;
- }
-
- @Override
- public Drawable peekWallpaper() {
- return null;
- }
-
- @Override
- public int getWallpaperDesiredMinimumWidth() {
- return 0;
- }
-
- @Override
- public int getWallpaperDesiredMinimumHeight() {
- return 0;
- }
-
- @Override
- public void setWallpaper(Bitmap bitmap) throws IOException {
-
- }
-
- @Override
- public void setWallpaper(InputStream data) throws IOException {
-
- }
-
- @Override
- public void clearWallpaper() throws IOException {
-
- }
-
- @Override
- public void startActivity(Intent intent) {
-
- }
-
- @Override
- public void startActivity(Intent intent, @Nullable Bundle options) {
-
- }
-
- @Override
- public void startActivities(Intent[] intents) {
-
- }
-
- @Override
- public void startActivities(Intent[] intents, Bundle options) {
-
- }
-
- @Override
- public void startIntentSender(IntentSender intent, @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) throws IntentSender.SendIntentException {
-
- }
-
- @Override
- public void startIntentSender(IntentSender intent, @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, @Nullable Bundle options) throws IntentSender.SendIntentException {
-
- }
-
- @Override
- public void sendBroadcast(Intent intent) {
-
- }
-
- @Override
- public void sendBroadcast(Intent intent, @Nullable String receiverPermission) {
-
- }
-
- @Override
- public void sendOrderedBroadcast(Intent intent, @Nullable String receiverPermission) {
-
- }
-
- @Override
- public void sendOrderedBroadcast(@NonNull Intent intent, @Nullable String receiverPermission, @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler, int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras) { }
- @Override
- public void sendBroadcastAsUser(Intent intent, UserHandle user) {
-
- }
-
- @Override
- public void sendBroadcastAsUser(Intent intent, UserHandle user, @Nullable String receiverPermission) {
-
- }
-
- @Override
- public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, @Nullable String receiverPermission, BroadcastReceiver
- resultReceiver, @Nullable Handler scheduler, int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras) {
-
- }
-
- @Override
- public void sendStickyBroadcast(Intent intent) {
-
- }
-
- @Override
- public void sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, @Nullable Handler scheduler, int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras) {
-
- }
-
- @Override
- public void removeStickyBroadcast(Intent intent) {
-
- }
-
- @Override
- public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
-
- }
-
- @Override
- public void sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user, BroadcastReceiver resultReceiver, @Nullable Handler scheduler, int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras) {
-
- }
-
- @Override
- public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
-
- }
-
- @Nullable
- @Override
- public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) {
- return null;
- }
-
- @Nullable
- @Override
- public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter, int flags) {
- return null;
- }
-
- @Nullable
- @Override
- public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, @Nullable String broadcastPermission, @Nullable Handler scheduler) {
- return null;
- }
-
- @Nullable
- @Override
- public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, @Nullable String broadcastPermission, @Nullable Handler scheduler, int flags) {
- return null;
- }
-
- @Override
- public void unregisterReceiver(BroadcastReceiver receiver) {
-
- }
-
- @Nullable
- @Override
- public ComponentName startService(Intent service) {
- return null;
- }
-
- @Nullable
- @Override
- public ComponentName startForegroundService(Intent service) {
- return null;
- }
-
- @Override
- public boolean stopService(Intent service) {
- return false;
- }
-
- @Override
- public boolean bindService(Intent service, @NonNull ServiceConnection conn, int flags) {
- return false;
- }
-
- @Override
- public void unbindService(@NonNull ServiceConnection conn) {
-
- }
-
- @Override
- public boolean startInstrumentation(@NonNull ComponentName className, @Nullable String profileFile, @Nullable Bundle arguments) {
- return false;
- }
-
- @Nullable
- @Override
- public Object getSystemService(@NonNull String name) {
- return null;
- }
-
- @Nullable
- @Override
- public String getSystemServiceName(@NonNull Class> serviceClass) {
- return null;
- }
-
- @Override
- public int checkPermission(@NonNull String permission, int pid, int uid) {
- return 0;
- }
-
- @Override
- public int checkCallingPermission(@NonNull String permission) {
- return 0;
- }
-
- @Override
- public int checkCallingOrSelfPermission(@NonNull String permission) {
- return 0;
- }
-
- @Override
- public int checkSelfPermission(@NonNull String permission) {
- return 0;
- }
-
- @Override
- public void enforcePermission(@NonNull String permission, int pid, int uid, @Nullable String message) {
-
- }
-
- @Override
- public void enforceCallingPermission(@NonNull String permission, @Nullable String message) {
-
- }
-
- @Override
- public void enforceCallingOrSelfPermission(@NonNull String permission, @Nullable String message) {
-
- }
-
- @Override
- public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
-
- }
-
- @Override
- public void revokeUriPermission(Uri uri, int modeFlags) {
-
- }
-
- @Override
- public void revokeUriPermission(String toPackage, Uri uri, int modeFlags) {
-
- }
-
- @Override
- public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
- return 0;
- }
-
- @Override
- public int checkCallingUriPermission(Uri uri, int modeFlags) {
- return 0;
- }
-
- @Override
- public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
- return 0;
- }
-
- @Override
- public int checkUriPermission(@Nullable Uri uri, @Nullable String readPermission, @Nullable String writePermission, int pid, int uid, int modeFlags) {
- return 0;
- }
-
- @Override
- public void enforceUriPermission(Uri uri, int pid, int uid, int modeFlags, String message) {
-
- }
-
- @Override
- public void enforceCallingUriPermission(Uri uri, int modeFlags, String message) {
-
- }
-
- @Override
- public void enforceCallingOrSelfUriPermission(Uri uri, int modeFlags, String message) {
-
- }
-
- @Override
- public void enforceUriPermission(@Nullable Uri uri, @Nullable String readPermission, @Nullable String writePermission, int pid, int uid, int modeFlags, @Nullable String message) {
-
- }
-
- @Override
- public Context createPackageContext(String packageName, int flags) throws PackageManager.NameNotFoundException {
- return null;
- }
-
- @Override
- public Context createContextForSplit(String splitName) throws PackageManager.NameNotFoundException {
- return null;
- }
-
- @Override
- public Context createConfigurationContext(@NonNull Configuration overrideConfiguration) {
- return null;
- }
-
- @Override
- public Context createDisplayContext(@NonNull Display display) {
- return null;
- }
-
- @Override
- public Context createDeviceProtectedStorageContext() {
- return null;
- }
-
- @Override
- public boolean isDeviceProtectedStorage() {
- return false;
- }
- }
-
diff --git a/app/src/test/java/foundation/e/drive/Test/mockObject/mockRemoteFile.java b/app/src/test/java/foundation/e/drive/Test/mockObject/mockRemoteFile.java
deleted file mode 100644
index fcdedb31f2adb6ddc50b1f833e0d1b0bab136c4d..0000000000000000000000000000000000000000
--- a/app/src/test/java/foundation/e/drive/Test/mockObject/mockRemoteFile.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package foundation.e.drive.Test.mockObject;
-
-import com.owncloud.android.lib.resources.files.model.RemoteFile;
-
-public class mockRemoteFile extends RemoteFile {
- public mockRemoteFile(){};
-}
diff --git a/app/src/test/java/foundation/e/drive/Test/mockObject/mockSfs.java b/app/src/test/java/foundation/e/drive/Test/mockObject/mockSfs.java
deleted file mode 100644
index 01d69d08bf72d2d1f86df8dab731723c32ddd09a..0000000000000000000000000000000000000000
--- a/app/src/test/java/foundation/e/drive/Test/mockObject/mockSfs.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package foundation.e.drive.Test.mockObject;
-
-import foundation.e.drive.models.SyncedFileState;
-
-public class mockSfs extends SyncedFileState {
- public mockSfs(){}
-}
diff --git a/app/src/test/java/foundation/e/drive/TestUtils.java b/app/src/test/java/foundation/e/drive/TestUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..159609daf5f2e89b8cf930eecca215734652220b
--- /dev/null
+++ b/app/src/test/java/foundation/e/drive/TestUtils.java
@@ -0,0 +1,147 @@
+package foundation.e.drive;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.content.Context;
+
+import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.network.CertificateCombinedException;
+import com.owncloud.android.lib.common.network.NetworkUtils;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.lib.resources.status.GetRemoteStatusOperation;
+
+import org.junit.BeforeClass;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import static com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_OC_BASE_URL;
+import static org.junit.Assert.assertTrue;
+import static org.robolectric.Shadows.shadowOf;
+
+public abstract class TestUtils {
+ public static final String TEST_LOCAL_ROOT_FOLDER_PATH = "/tmp/eDrive/test/"; //THis is where test file and folder for synchronisatio will be stored
+ public static final String TEST_REMOTE_ROOT_FOLDER_PATH ="/eDrive-test/";
+ public static String TEST_ACCOUNT_TYPE ="eelo";
+ public static String TEST_SERVER_URI;
+ public static String TEST_ACCOUNT_NAME;
+
+ private static String TEST_ACCOUNT_PASSWORD; //Shouldn't be accessible from outside
+ private static Account validAccount;
+
+
+ /**
+ * This method execute before the class, it assure that credentials are available
+ */
+ public static void loadServerCredentials(){
+ TEST_ACCOUNT_PASSWORD = BuildConfig.testAccountPWd;
+ TEST_ACCOUNT_NAME = BuildConfig.testAccountName;
+ TEST_SERVER_URI = BuildConfig.testServerUrl;
+ }
+
+
+ /**
+ * Get the valid Account object. Create it if it isn't already instanciated
+ * @return
+ */
+ public static Account getValidAccount(){
+ if(validAccount == null){
+ System.out.println("Account name = "+TEST_ACCOUNT_NAME);
+ validAccount = new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE);
+ }
+ return validAccount;
+ }
+
+ /**
+ * register in accountManager an account with name, password, type and server url provided at build
+ */
+ public static void prepareValidAccount(AccountManager accountManager){
+ storeAccountInManager(getValidAccount(), TEST_ACCOUNT_PASSWORD, TEST_SERVER_URI, accountManager);
+ }
+
+
+ public static void storeAccountInManager(Account account, String password, String serverUrl, AccountManager manager){
+ shadowOf(manager).addAccount(account); // Commenting this make failure due to JobUtils.stopScheduleJob()" method...
+ shadowOf(manager).setPassword(account, password);
+ shadowOf(manager).setUserData(account, KEY_OC_BASE_URL, serverUrl);
+ }
+
+ /**
+ * Test the connexion to the server
+ * Add the certificate to the knownServerCertificateStore if required
+ * @throws KeyStoreException
+ * @throws CertificateException
+ * @throws NoSuchAlgorithmException
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ public static void testConnection(OwnCloudClient client, Context context) throws KeyStoreException,
+ CertificateException,
+ NoSuchAlgorithmException,
+ IOException,
+ InterruptedException{
+
+ GetRemoteStatusOperation getStatus = new GetRemoteStatusOperation(context);
+
+ RemoteOperationResult result = getStatus.execute(client);
+
+ if (result.isSuccess()) {
+ Log_OC.d("AbstractIT", "Connection to server successful");
+ } else {
+ if (RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED.equals(result.getCode())) {
+ Log_OC.d("AbstractIT", "Accepting certificate");
+
+ CertificateCombinedException exception = (CertificateCombinedException) result.getException();
+ X509Certificate certificate = exception.getServerCertificate();
+
+ NetworkUtils.addCertToKnownServersStore(certificate, context);
+ Thread.sleep(1000);
+
+ // retry
+ getStatus = new GetRemoteStatusOperation(context);
+ result = getStatus.execute(client);
+
+ if (!result.isSuccess()) {
+ throw new RuntimeException("No connection to server possible, even with accepted cert");
+ }
+
+ } else {
+ throw new RuntimeException("No connection to server possible");
+ }
+ }
+ }
+
+
+ /**
+ * Method adapted from https://github.com/nextcloud/android/blob/master/src/androidTest/java/com/owncloud/android/AbstractIT.java
+ * @param filePath path of the file to create
+ * @param iteration number of time to write dummy content
+ * @return the File instance
+ * @throws IOException
+ * @throws SecurityException
+ */
+ public static File createFile(String filePath, int iteration) throws IOException, SecurityException{
+ File file = new File(filePath);
+ if (!file.getParentFile().exists()) {
+ assertTrue(file.getParentFile().mkdirs());
+ }
+
+ file.createNewFile();
+
+ FileWriter writer = new FileWriter(file);
+
+ for (int i = 0; i < iteration; i++) {
+ writer.write("123123123123123123123123123\n");
+ }
+ writer.flush();
+ writer.close();
+
+ return file;
+ }
+}
diff --git a/app/src/test/java/foundation/e/drive/operations/UploadFileOperationTest.java b/app/src/test/java/foundation/e/drive/operations/UploadFileOperationTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c01da6f62b5e358f9ca67a8150611380e996e57
--- /dev/null
+++ b/app/src/test/java/foundation/e/drive/operations/UploadFileOperationTest.java
@@ -0,0 +1,272 @@
+package foundation.e.drive.operations;
+
+import android.accounts.AccountManager;
+import android.os.Build;
+
+import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.UserInfo;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.resources.users.GetRemoteUserInfoOperation;
+
+import junit.framework.Assert;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowLog;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import foundation.e.drive.BuildConfig;
+import foundation.e.drive.database.DbHelper;
+import foundation.e.drive.models.SyncedFileState;
+import foundation.e.drive.models.SyncedFolder;
+import foundation.e.drive.TestUtils;
+import foundation.e.drive.utils.CommonUtils;
+
+
+@RunWith(RobolectricTestRunner.class)
+@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.O, manifest = Config.NONE)
+public class UploadFileOperationTest {
+
+ private List syncedFileStates= new ArrayList<>();
+ private OwnCloudClient client;
+ private AccountManager accountManager;
+
+ private long userFreeQuota;
+
+ public UploadFileOperationTest(){
+ TestUtils.loadServerCredentials();
+ accountManager = AccountManager.get(RuntimeEnvironment.application);
+ TestUtils.prepareValidAccount(accountManager);
+ ShadowLog.stream = System.out;
+ client = CommonUtils.getOwnCloudClient(CommonUtils.getAccount(TestUtils.TEST_ACCOUNT_NAME, TestUtils.TEST_ACCOUNT_TYPE, accountManager), RuntimeEnvironment.application);
+
+ try {
+ TestUtils.testConnection(client, RuntimeEnvironment.application);
+ }catch(Exception e){
+ System.out.println("test connection failed: "+e.getMessage());
+ }
+ userFreeQuota = getUserRemoteFreeQuota();
+ }
+
+ @Before
+ public void setUp(){
+ prepareDB(); //Create DB
+ Assert.assertNotNull("Client is null. unexpected!", client);
+ }
+
+ @After
+ public void tearDown(){
+ }
+
+ /**
+ * Prepare content of database for test
+ */
+ private void prepareDB(){
+ //Insert three test folder: small, medium, large
+
+
+ DbHelper.insertSyncedFolder(createSyncedFolder("small"), RuntimeEnvironment.application);
+ DbHelper.insertSyncedFolder(createSyncedFolder("medium"), RuntimeEnvironment.application);
+ DbHelper.insertSyncedFolder(createSyncedFolder("large"), RuntimeEnvironment.application);
+
+ //Insert at least one file for each folder
+ Assert.assertEquals("There isn't three folder in DB as expected", 3, DbHelper.getSyncedFolderList(RuntimeEnvironment.application, true).size());
+ }
+
+ /**
+ * Create the syncedFolder instance
+ * @param name the name of the folder
+ * @return SyncedFolder instance
+ */
+ private SyncedFolder createSyncedFolder(String name){
+ return new SyncedFolder(name, TestUtils.TEST_LOCAL_ROOT_FOLDER_PATH+name+"/", TestUtils.TEST_REMOTE_ROOT_FOLDER_PATH+name+"/", true, true, true, true);
+ }
+
+ /**
+ * Create local file to use for upload test
+ */
+ private void createSmallFile(){
+
+ final String smallDummyFilePath = TestUtils.TEST_LOCAL_ROOT_FOLDER_PATH+"small/dummy.txt";
+ try {
+ TestUtils.createFile(smallDummyFilePath, 2);
+ } catch (IOException | SecurityException e ) {
+ Assert.fail(e.getMessage());
+ }
+
+ final SyncedFileState sfs = new SyncedFileState(-1, "dummy.txt", TestUtils.TEST_LOCAL_ROOT_FOLDER_PATH+"small/dummy.txt", TestUtils.TEST_REMOTE_ROOT_FOLDER_PATH+"small/dummy.txt", "", 0l, 0, true);
+ sfs.setId(DbHelper.manageSyncedFileStateDB(sfs, "INSERT", RuntimeEnvironment.application));
+
+ syncedFileStates.add(sfs);
+ }
+
+ /**
+ * Remove SmallFile locally and remotly if it exist
+ * This method has just been made to make basic test to work
+ * It should be refactored for next state, and test improvement
+ * @return true if file deleted or if it doesn't exist
+ */
+ private boolean removeSmallFile(){
+ if(!syncedFileStates.isEmpty()) {
+ final SyncedFileState sfs = syncedFileStates.get(0);
+ if (sfs != null) {
+ RemoveFileOperation removeRemoteFileOp = new RemoveFileOperation(sfs);
+ removeRemoteFileOp.execute(client);
+ }
+ }
+
+ final String smallDummyFilePath = TestUtils.TEST_LOCAL_ROOT_FOLDER_PATH+"small/dummy.txt";
+ File smallFile = new File(smallDummyFilePath);
+ if(smallFile.exists()){
+ return smallFile.delete();
+ }else return true;
+ }
+
+ private long getUserRemoteFreeQuota(){
+ GetRemoteUserInfoOperation getRemoteUserInfoOperation = new GetRemoteUserInfoOperation();
+ RemoteOperationResult ocsResult = getRemoteUserInfoOperation.execute(client);
+
+ if(ocsResult.isSuccess() && ocsResult.getData() != null) {
+ UserInfo userInfo = (UserInfo) ocsResult.getData().get(0);
+ System.out.println("User free Quotas: "+userInfo.getQuota().getFree());
+ System.out.println("User Total Quotas: "+userInfo.getQuota().getTotal());
+
+ return userInfo.getQuota().getFree();
+ }
+ return -1;
+ }
+
+ /**
+ * test upload of a file and check that it's ok
+ */
+ @Test
+ public void uploadNewSmallFile_shouldwork(){
+ //tearDown
+ removeSmallFile(); //clean the environnement
+ createSmallFile(); //preparation
+
+ final SyncedFileState sfs_fromDB = DbHelper.loadSyncedFile(RuntimeEnvironment.application, syncedFileStates.get(0).getLocalPath(), true);
+ Assert.assertTrue("SyncedFileState loaded from DB must have an empty Etag", sfs_fromDB.getLastETAG().isEmpty());
+
+
+ boolean checkEtag = false;
+ UploadFileOperation testOperation = new UploadFileOperation(syncedFileStates.get(0), checkEtag);
+ testOperation.setContext(RuntimeEnvironment.application); //Without it, it won't update database
+
+ RemoteOperationResult result = testOperation.execute(client);
+ String errorMsg = "The upload failed:\n http code: "+result.getHttpCode()
+ +"\n, is success ?"+result.isSuccess()
+ +"\n, log msg: "+result.getLogMessage()
+ +"\n, is server fail ? "+result.isServerFail();
+ if(result.getException() != null){
+ errorMsg += "\n, exception msg: "+result.getException().getMessage();
+ }
+ Assert.assertTrue( errorMsg, result.isSuccess());
+
+ final SyncedFileState sfs_fromDBAfterUpload = DbHelper.loadSyncedFile(RuntimeEnvironment.application, syncedFileStates.get(0).getLocalPath(), true);
+ Assert.assertFalse("After upload, the database must store the etag of the syncedFileState. But here it is empty", sfs_fromDBAfterUpload.getLastETAG().isEmpty());
+ }
+
+
+
+
+ /**
+ * Try to upload a file with a null SyncedFileState instance
+ * Must return a "Forbidden" result code
+ */
+ @Ignore("Ignored until UploadFileOperation has fixed the NPE")
+ @Test
+ public void nullSyncedFileState_shouldFail(){
+
+ //Test fails at the moment because of UploadFileOperation's constructor not checking for syncedFileState is null)
+ // check https://gitlab.e.foundation/e/apps/eDrive/-/issues/120
+ UploadFileOperation testOperation = new UploadFileOperation(null, false);
+ testOperation.setContext(RuntimeEnvironment.application);
+
+ RemoteOperationResult result = testOperation.execute(client);
+ Assert.assertEquals("Expected result code was FORBIDDEN but got: "+result.getCode().name(), RemoteOperationResult.ResultCode.FORBIDDEN, result.getCode());
+ }
+
+
+ /**
+ * Try to upload local file that has been removed between uploadOperation's creation and
+ * ploadOperation execution
+ */
+ @Test
+ public void localFileRemovedBeforeUpload_shouldFail(){
+ removeSmallFile(); //clean the environnement
+ createSmallFile(); //preparation
+
+ final SyncedFileState sfs_fromDB = DbHelper.loadSyncedFile(RuntimeEnvironment.application, syncedFileStates.get(0).getLocalPath(), true);
+ Assert.assertTrue("SyncedFileState loaded from DB must have an empty Etag", sfs_fromDB.getLastETAG().isEmpty());
+
+ boolean checkEtag = false;
+ UploadFileOperation testOperation = new UploadFileOperation(syncedFileStates.get(0), checkEtag);
+
+ File smallFile = new File(sfs_fromDB.getLocalPath());
+ Assert.assertTrue("Local file deletion return false instead of true", smallFile.delete());
+
+ RemoteOperationResult result = testOperation.execute(client);
+ Assert.assertEquals("Expected result code was FORBIDDEN but got: "+result.getCode().name(), RemoteOperationResult.ResultCode.FORBIDDEN, result.getCode());
+ }
+
+
+ /**
+ * Assert that uploading a file that is bigger than free quotas isn't allowed
+ */
+ @Test
+ public void fileSizeBiggerThanFreeQuota_shouldnotBeAllowed(){
+ //long freeQuota = getUserRemoteFreeQuota();
+ Assert.assertFalse("Reading remote free quota fails"+userFreeQuota, -1 == userFreeQuota);
+ //We don't care of parameter of UploadFileOperation's constructor
+ RemoteOperationResult actualResult = new UploadFileOperation(Mockito.mock(SyncedFileState.class), false)
+ .checkAvailableSpace(client, (userFreeQuota+1));
+ Assert.assertEquals("Quota check ("+ userFreeQuota+"vs"+(userFreeQuota+1)+") failed", RemoteOperationResult.ResultCode.QUOTA_EXCEEDED, actualResult.getCode());
+ }
+
+ /**
+ * Assert that uploading a file which size is exactly the amount of free quota isn't allowed
+ *
+ */
+ @Test
+ public void fileSizeEqualToFreeQuota_shouldnotBeAllowed(){
+ //I don't know why but it always fail for this test.
+ //long freeQuota = getUserRemoteFreeQuota();
+ Assert.assertFalse("Reading remote free quota fails"+userFreeQuota, -1 == userFreeQuota);
+
+ RemoteOperationResult actualResult = new UploadFileOperation(Mockito.mock(SyncedFileState.class), false)
+ .checkAvailableSpace(client, userFreeQuota);
+ Assert.assertEquals("Quota check ("+ userFreeQuota+" vs "+userFreeQuota+") failed",
+ RemoteOperationResult.ResultCode.QUOTA_EXCEEDED,
+ actualResult.getCode());
+ }
+
+
+ /**
+ * Assert that uploading a file which size is lower than the amount of free quota is allowed
+ *
+ */
+ @Test
+ public void fileSizeSmallerThanFreeQuota_shouldBeAllowed(){
+ //long freeQuota = getUserRemoteFreeQuota();
+ Assert.assertFalse("Reading remote free quota fails "+userFreeQuota, -1 == userFreeQuota);
+
+ RemoteOperationResult actualResult = new UploadFileOperation(Mockito.mock(SyncedFileState.class), false)
+ .checkAvailableSpace(client, (userFreeQuota-1));
+ Assert.assertEquals("Quota check ("+ userFreeQuota+" vs "+(userFreeQuota-1)+") failed",
+ RemoteOperationResult.ResultCode.OK,
+ actualResult.getCode());
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/test/java/foundation/e/drive/services/AbstractServiceIT.java b/app/src/test/java/foundation/e/drive/services/AbstractServiceIT.java
new file mode 100644
index 0000000000000000000000000000000000000000..810a7640c7ffd828cc734fa02aab028dddfa6079
--- /dev/null
+++ b/app/src/test/java/foundation/e/drive/services/AbstractServiceIT.java
@@ -0,0 +1,121 @@
+package foundation.e.drive.services;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.Service;
+import android.app.job.JobScheduler;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+import android.os.Build;
+
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.android.controller.ServiceController;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowLog;
+
+import foundation.e.drive.BuildConfig;
+import foundation.e.drive.TestUtils;
+import foundation.e.drive.database.DbHelper;
+import foundation.e.drive.utils.AppConstants;
+import static foundation.e.drive.TestUtils.TEST_ACCOUNT_NAME;
+import static foundation.e.drive.TestUtils.TEST_ACCOUNT_TYPE;
+import static foundation.e.drive.utils.AppConstants.MEDIASYNC_PROVIDER_AUTHORITY;
+import static foundation.e.drive.utils.AppConstants.SETTINGSYNC_PROVIDER_AUTHORITY;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.O, manifest = Config.NONE)
+public abstract class AbstractServiceIT {
+
+ /**
+ * By making the below field static it is done once
+ * for all test class that extends this instead of
+ * one time by class.
+ */
+ protected static Context context;
+
+ protected T mService;
+ protected ServiceController mServiceController;
+
+ protected AccountManager accountManager;
+ protected ContentResolver contentResolver;
+ protected SharedPreferences sharedPreferences;
+ protected ConnectivityManager connectivityManager;
+ protected JobScheduler jobScheduler;
+ protected DbHelper dbHelper;
+
+ protected int initial_folder_number=0; //number of folders to sync at initialization
+ protected long last_sync_time=0l; //Timestamp of the end of the last synchronisation
+ protected boolean init_done = true; //true if InitializerService did its job
+ protected boolean oms_running=false; //true if OperationManagerService is already running
+
+ @BeforeClass
+ public static void beforeAll(){
+ TestUtils.loadServerCredentials();
+ ShadowLog.stream = System.out; //give access to log
+ }
+
+ /**
+ * Create and register one validAccount
+ */
+ protected void prepareValidAccount(){
+ TestUtils.prepareValidAccount(accountManager);
+ }
+
+ /**
+ * enable Media & settings sync
+ */
+ protected void enableMediaAndSettingsSync(Account account){ //replace this by robolectric the contentResolver
+ contentResolver.setSyncAutomatically(account, MEDIASYNC_PROVIDER_AUTHORITY, true);
+ contentResolver.setSyncAutomatically(account, SETTINGSYNC_PROVIDER_AUTHORITY, true);
+ }
+
+ /**
+ * disable Media & enable settings sync
+ */
+ protected void disableMediaSync(Account account){ //replace this by robolectric the contentResolver
+ contentResolver.setSyncAutomatically(account, MEDIASYNC_PROVIDER_AUTHORITY, false);
+ contentResolver.setSyncAutomatically(account, SETTINGSYNC_PROVIDER_AUTHORITY, true);
+ }
+
+ /**
+ * enable Media and disable settings sync
+ */
+ protected void disableSettingsSync(Account account){ //replace this by robolectric the contentResolver
+ contentResolver.setSyncAutomatically(account, MEDIASYNC_PROVIDER_AUTHORITY, true);
+ contentResolver.setSyncAutomatically(account, SETTINGSYNC_PROVIDER_AUTHORITY, false);
+ }
+
+ /**
+ * disable Media & settings sync
+ */
+ protected void disableMediaAndSettingsSync(Account account){ //replace this by robolectric the contentResolver
+ contentResolver.setSyncAutomatically(account, MEDIASYNC_PROVIDER_AUTHORITY, false);
+ contentResolver.setSyncAutomatically(account, SETTINGSYNC_PROVIDER_AUTHORITY, false);
+ }
+
+ /**
+ * Register sharedPreferences common to all services
+ * - OMS is working (bool)
+ * - Account name (String)
+ * - Account type (String)
+ * - initial folders number (int)
+ * - last sync time (long)
+ * - Initialization has been done (bool)
+ *
+ * Use default value of the instance field
+ * So update the field before to call this to store specific value
+ */
+ protected void registerSharedPref(){
+ sharedPreferences.edit().putBoolean( AppConstants.INITIALIZATION_HAS_BEEN_DONE, init_done)
+ .putBoolean(AppConstants.KEY_OMS_IS_WORKING, oms_running)
+ .putString(AccountManager.KEY_ACCOUNT_NAME, TEST_ACCOUNT_NAME)
+ .putString(AccountManager.KEY_ACCOUNT_TYPE, TEST_ACCOUNT_TYPE)
+ .putInt(AppConstants.INITIALFOLDERS_NUMBER, initial_folder_number)
+ .putLong(AppConstants.KEY_LAST_SYNC_TIME, last_sync_time)
+ .commit();
+ }
+}
diff --git a/app/src/test/java/foundation/e/drive/services/InitializerServiceTest.java b/app/src/test/java/foundation/e/drive/services/InitializerServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0de9195bbe24fae76a613541de3f63be5d74e5d9
--- /dev/null
+++ b/app/src/test/java/foundation/e/drive/services/InitializerServiceTest.java
@@ -0,0 +1,119 @@
+package foundation.e.drive.services;
+
+
+import android.accounts.AccountManager;
+import android.app.job.JobScheduler;
+import android.content.Context;
+import android.net.ConnectivityManager;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowLog;
+
+import foundation.e.drive.TestUtils;
+import foundation.e.drive.database.DbHelper;
+import foundation.e.drive.utils.AppConstants;
+
+import static org.robolectric.Shadows.shadowOf;
+
+
+public class InitializerServiceTest extends AbstractServiceIT{
+
+ public InitializerServiceTest(){
+
+ mServiceController = Robolectric.buildService(InitializerService.class);
+ mService = mServiceController.get();
+ context = RuntimeEnvironment.application;
+ accountManager = AccountManager.get(context);
+ jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+ contentResolver = context.getContentResolver();
+ sharedPreferences = context.getSharedPreferences( AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE);
+ connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ dbHelper = new DbHelper(context);
+
+ init_done = false;
+ }
+
+ /**
+ * Check that the initializer service stops if the Initialization parameters
+ * is setted to true
+ */
+ @Test
+ public void InitAlreadyDone_shouldStop(){
+ init_done = true;
+ registerSharedPref();
+
+ Assert.assertTrue("SharedPreferences.INITIALIZATION_HAS_BEEN_DONE expected to be true but was false", sharedPreferences.getBoolean(AppConstants.INITIALIZATION_HAS_BEEN_DONE, false));
+
+ mServiceController.create().startCommand(0,0);
+ String lastLog = ShadowLog.getLogs().get(ShadowLog.getLogs().size()-1).msg;
+ Assert.assertEquals("lastLog expected to be 'Initializer has already been run' but was "+lastLog, "Initializer has already been run", lastLog);
+ Assert.assertEquals("service should have schedule a job but pending job contains "+jobScheduler.getAllPendingJobs().size(),1, jobScheduler.getAllPendingJobs().size());
+ //Teardown
+ jobScheduler.cancelAll();
+ }
+
+ /**
+ * This check the case where InitializationService stopped previously after
+ * account registration but before folder initializations.
+ */
+ @Test
+ public void initNotDoneButAccountRegistered_shouldWork(){
+ registerSharedPref();
+ prepareValidAccount();
+ enableMediaAndSettingsSync(TestUtils.getValidAccount());
+ /*try {
+ testConnection(CommonUtils.getOwnCloudClient(validAccount, context));
+ }catch(Exception e){
+ Assert.fail(e.getMessage());
+ }*/
+ mServiceController.create().startCommand(0,0);
+ //mService.onRemoteOperationFinish(new CreateInitialFolderRemoteOperation(null, true, context), new RemoteOperationResult(true, new MkColMethod("")));
+
+ //Assert.fail("Not yet implemented");
+ }
+
+ /**
+ * This check the case where no account where provided with the intent
+ * and initialization hadn't been run before
+ */
+ @Test
+ public void noAccountInIntentNorInPrefs_shouldstop(){
+ registerSharedPref();
+ sharedPreferences.edit().putString(AccountManager.KEY_ACCOUNT_NAME, "")
+ .putString(AccountManager.KEY_ACCOUNT_TYPE, "").commit();
+ enableMediaAndSettingsSync(TestUtils.getValidAccount());
+ mServiceController.create().startCommand(0,0);
+
+ String lastLog = ShadowLog.getLogs().get(ShadowLog.getLogs().size()-1).msg;
+ Assert.assertEquals("lastLog expected to be 'Account's name not found. Neither in shared prefs nor in intent's extras' but was "+lastLog, "Account's name not found. Neither in shared prefs nor in intent's extras", lastLog);
+ }
+
+
+ /**
+ * Check that InitializerService stops if media & settings sync are disabled
+ */
+ @Test
+ public void settingsAndMediaSyncDisabled_shouldStop(){
+ initial_folder_number = -1;
+ init_done = false;
+ registerSharedPref();
+ final int initFolderCount_pretest = sharedPreferences.getInt(AppConstants.INITIALFOLDERS_NUMBER, 0);
+ Assert.assertEquals("Initial folders count expected to be -1 but got "+initFolderCount_pretest, -1, initFolderCount_pretest);
+
+ prepareValidAccount();
+ disableMediaAndSettingsSync(TestUtils.getValidAccount());
+
+ mServiceController.create();
+ mServiceController.startCommand(0,0);
+
+ final int initFolderCount = sharedPreferences.getInt(AppConstants.INITIALFOLDERS_NUMBER, -1);
+ Assert.assertEquals("Initial folders count expected to be 0 but got "+initFolderCount, 0, initFolderCount);
+
+ final boolean initialization_done = sharedPreferences.getBoolean(AppConstants.INITIALIZATION_HAS_BEEN_DONE, false);
+ Assert.assertTrue("sharedPref initialization_done expected to be true but was false"+initialization_done, initialization_done);
+ }
+}
diff --git a/app/src/test/java/foundation/e/drive/services/ObserverServiceTest.java b/app/src/test/java/foundation/e/drive/services/ObserverServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a01a141ed51d933cbef4ee0c783979ae807d66da
--- /dev/null
+++ b/app/src/test/java/foundation/e/drive/services/ObserverServiceTest.java
@@ -0,0 +1,308 @@
+package foundation.e.drive.services;
+
+import android.accounts.AccountManager;
+import android.app.job.JobScheduler;
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+
+import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+
+import junit.framework.Assert;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowLog;
+import org.robolectric.shadows.ShadowNetworkInfo;
+
+import java.io.File;
+import java.util.List;
+
+import foundation.e.drive.TestUtils;
+import foundation.e.drive.database.DbHelper;
+import foundation.e.drive.models.SyncedFolder;
+import foundation.e.drive.operations.CreateInitialFolderRemoteOperation;
+import foundation.e.drive.utils.AppConstants;
+import foundation.e.drive.utils.CommonUtils;
+import foundation.e.drive.utils.JobUtils;
+
+import static foundation.e.drive.TestUtils.TEST_LOCAL_ROOT_FOLDER_PATH;
+import static foundation.e.drive.TestUtils.TEST_REMOTE_ROOT_FOLDER_PATH;
+import static foundation.e.drive.TestUtils.getValidAccount;
+import static foundation.e.drive.utils.AppConstants.INITIALIZATION_HAS_BEEN_DONE;
+import static foundation.e.drive.utils.AppConstants.MEDIA_SYNCABLE_CATEGORIES;
+import static org.robolectric.Shadows.shadowOf;
+
+/**
+ * The RunWith & Config annotation are done in the AbstractServiceIT
+ */
+public class ObserverServiceTest extends AbstractServiceIT {
+
+ public ObserverServiceTest(){
+ mServiceController = Robolectric.buildService(ObserverService.class);
+ mService = mServiceController.get();
+ context = RuntimeEnvironment.application;
+ accountManager = AccountManager.get(context);
+ jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+ contentResolver = context.getContentResolver();
+ sharedPreferences = context.getSharedPreferences( AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE);
+ connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ dbHelper = new DbHelper(context);
+ }
+
+ /**
+ * Schedule a ScannerJob instance in JobScheduler
+ */
+ private void registerScannerJobInJobScheduler(){
+ Assert.assertTrue("jobScheduler expected to be have no pending job",jobScheduler.getAllPendingJobs().isEmpty());
+
+ JobUtils.scheduleScannerJob(context);
+ int scheduledJobListSize = jobScheduler.getAllPendingJobs().size();
+ Assert.assertEquals("PendingJob size expected to be 1 but was:"+scheduledJobListSize,1, scheduledJobListSize );
+
+ }
+
+
+ /**
+ * Set the network status to an available wifi
+ */
+ private void setWifiNetworkStatus(){
+ NetworkInfo netInfo = ShadowNetworkInfo.newInstance(null,
+ ConnectivityManager.TYPE_WIFI, 0, true, NetworkInfo.State.CONNECTED);
+ Assert.assertEquals("NetworkInfo type is invalid",ConnectivityManager.TYPE_WIFI,netInfo.getType());
+ shadowOf(connectivityManager).setActiveNetworkInfo(netInfo);
+ }
+
+ /**
+ * Create a network status where no connection is available
+ */
+ private void setUnavailableWifiNetworkStatus(){
+ //shadowOf(connectivityManager).clearAllNetworks(); // doesn't work...
+
+ /*for(Network network : shadowOf (connectivityManager).getAllNetworks()){
+ shadowOf(connectivityManager).removeNetwork(network); // doesn't work...
+ }*/
+
+ NetworkInfo netInfo = ShadowNetworkInfo.newInstance(null,
+ ConnectivityManager.TYPE_WIFI, 0, true, NetworkInfo.State.DISCONNECTED);
+ Assert.assertEquals("NetworkInfo type is invalid",ConnectivityManager.TYPE_WIFI,netInfo.getType());
+
+ shadowOf(connectivityManager).setActiveNetworkInfo(netInfo);
+ }
+
+ /**
+ * Create a single 'SyncedFolder' instance for 'eDrive-test' folder
+ * @return SyncedFolder instance
+ */
+ private SyncedFolder createSingleTestSyncedFolder(){
+ final File folder = new File(TEST_LOCAL_ROOT_FOLDER_PATH);
+ try{
+ folder.mkdirs();
+ }catch(SecurityException e){
+ Assert.fail(e.getMessage());
+ }
+ final SyncedFolder sFolder = new SyncedFolder(MEDIA_SYNCABLE_CATEGORIES[0], TEST_LOCAL_ROOT_FOLDER_PATH, TEST_REMOTE_ROOT_FOLDER_PATH, true);
+
+ return sFolder;
+ }
+
+
+ /**
+ * Send request to server to create the remote folder of the given syncedFolder
+ * @param folder the local folder metadata to create
+ */
+ private void createRemoteFolder(SyncedFolder folder){
+ OwnCloudClient client = CommonUtils.getOwnCloudClient(getValidAccount(), context);
+
+ try {
+ TestUtils.testConnection(client, context);
+ }catch(Exception e){
+ System.out.println("Test connection failed :"+e.getMessage());
+ }
+
+ CreateInitialFolderRemoteOperation op = new CreateInitialFolderRemoteOperation(folder, true, context);
+ RemoteOperationResult result = op.execute(client); //Give SSL issue
+
+ Assert.assertTrue("Creation of remote test folder failed",result.isSuccess());
+
+ final int dbFolderListSize =DbHelper.getAllSyncedFolders(context).size();
+ Assert.assertEquals("Expected DB's SyncedFolder table content was 1, but got:"+dbFolderListSize, 1, dbFolderListSize);
+
+
+ initial_folder_number =1;
+ }
+
+
+ /**
+ * Run a test which correspond to a non blocking context
+ */
+ @Ignore("Ignore until a correct assertion has been found")
+ @Test
+ public void shouldWork() {
+ setWifiNetworkStatus();
+ prepareValidAccount();
+ enableMediaAndSettingsSync(getValidAccount());
+ createRemoteFolder(createSingleTestSyncedFolder());
+ registerScannerJobInJobScheduler();
+ registerSharedPref();
+
+ //Start the service
+ mServiceController.create().startCommand(0, 0);
+
+ List logs = ShadowLog.getLogs();
+ ShadowLog.LogItem lastLog = logs.get(logs.size()-3);
+
+ Assert.assertEquals("expected: 'Going to scan remote files' but found: '"+lastLog.msg, "Going to scan remote files", lastLog.msg);
+
+ //Tear down
+ mService.deleteDatabase(DbHelper.DATABASE_NAME);
+ //Assert.assertTrue("Database hasn't been removed", myService.deleteDatabase(DbHelper.DATABASE_NAME));
+ }
+
+
+
+
+ /**
+ * This assert that ObserverService doesn't start scanning remote or local if there is no network
+ */
+ @Ignore("Ignore until a way to prepare unavailable Network has been founded")
+ @Test
+ public void noNetwork_shouldStop(){
+ //setWifiNetworkStatus(); Make the test to fail as expected
+ //setUnavailableWifiNetworkStatus(); //Doesn't give the expected result at the moment so the test fails!
+ prepareValidAccount();
+ enableMediaAndSettingsSync(getValidAccount());
+ //createRemoteSyncedFolder(createSingleTestSyncedFolder());
+ registerScannerJobInJobScheduler();
+ registerSharedPref();
+
+ boolean haveNetworkConnexion = CommonUtils.haveNetworkConnexion(RuntimeEnvironment.application);
+ String msg = "CommonUtils.haveNetworkConnexion should return false but return "+haveNetworkConnexion;
+ Assert.assertFalse(msg, haveNetworkConnexion);
+
+ mServiceController.create().startCommand(0, 0);
+
+ List logs = ShadowLog.getLogs();
+ ShadowLog.LogItem lastLog = logs.get(logs.size()-1);
+ Assert.assertEquals("Last log isn't the one expected", "There is no Internet connexion.", lastLog.msg);
+
+ }
+
+
+ /**
+ * This assert that ObserverService won't start if the minimum delay between two sync isn't over
+ */
+ @Test
+ public void lastSyncWasLessThan15minAgo_shouldStop(){
+ last_sync_time = System.currentTimeMillis() - 899900;
+ setWifiNetworkStatus();
+ prepareValidAccount();
+ enableMediaAndSettingsSync(getValidAccount());
+ //createRemoteSyncedFolder(createSingleTestSyncedFolder());
+ registerScannerJobInJobScheduler();
+ registerSharedPref();
+
+ //Start the service
+ mServiceController.create().startCommand(0, 0);
+
+ //How to assert this... ?
+
+ List logs = ShadowLog.getLogs();
+ ShadowLog.LogItem lastLog = logs.get(logs.size()-1);
+
+ //Note: Checking log is the only way I've found to check that the service stopped as expected
+ Assert.assertEquals("Last log isn't the one expected", "Delay between now and last call is too short", lastLog.msg);
+
+ }
+
+ /**
+ * This assert that ObserverService will do its job if the minimum delay between two sync is over
+ */
+ @Test
+ public void lastSync15minAnd30secAgo_shouldStart(){
+ //decrease 15min and 30sec
+ last_sync_time = System.currentTimeMillis() - 930000;
+ setWifiNetworkStatus();
+ prepareValidAccount();
+ enableMediaAndSettingsSync(getValidAccount());
+ //createRemoteSyncedFolder(createSingleTestSyncedFolder());
+ registerScannerJobInJobScheduler();
+ registerSharedPref();
+
+ //Start the service
+ mServiceController.create().startCommand(0, 0);
+
+ List logs = ShadowLog.getLogs();
+ for(ShadowLog.LogItem log : logs){
+ Assert.assertFalse("Log shouldn't contains 'delay between now and last call is too short' but it does", log.msg.equals("Delay between now and last call is too short")); //There isn't assertNotEquals
+ }
+ }
+
+ /**
+ * This assert that ObserverService won't start if it's already running
+ */
+ @Ignore("Not yet implemented")
+ @Test
+ public void syncAlreadyStarted_shouldStop(){
+ //@TODO need to find how to access the "isRunning" private field inside the ObserverService for this test
+ Assert.fail("Not yet implemented ");
+ }
+
+
+ /**
+ * Check that service stop if no account provided
+ */
+ @Test
+ public void noAccount_shouldStop(){
+ registerScannerJobInJobScheduler(); //Assert that the ScheduledJob is present
+
+ mServiceController.create().startCommand(0, 0);
+
+ List logs = ShadowLog.getLogs();
+ ShadowLog.LogItem lastLog = logs.get(logs.size()-1);
+
+ Assert.assertEquals("Last expected log wasn't: 'No account registered' but "+lastLog.msg, "No account registered",lastLog.msg );
+ Assert.assertTrue("jobScheduler expected to be have no pending job",jobScheduler.getAllPendingJobs().isEmpty());
+ }
+
+ /**
+ * This test will assert that the ObserverService won't do its job
+ * if Initialization hasn't been done
+ */
+ @Test
+ public void InitializationNotDone_shouldStop(){
+ init_done = false; //This is the key settings for this test
+
+ setWifiNetworkStatus();
+ prepareValidAccount();
+ enableMediaAndSettingsSync(getValidAccount());
+ //createRemoteSyncedFolder(createSingleTestSyncedFolder());
+ registerScannerJobInJobScheduler();
+ registerSharedPref();
+
+
+ Assert.assertFalse("SharedPref doesn't contains the expected value for Initialization_has_been_done key", sharedPreferences.getBoolean(INITIALIZATION_HAS_BEEN_DONE, true));
+
+ mServiceController.create().startCommand(0, 0);
+ //How to assert this... ?
+
+ Intent expectedIntent = new Intent(mService, InitializerService.class);
+ Intent actualIntent = shadowOf(RuntimeEnvironment.application).getNextStartedService();
+
+ Assert.assertEquals("Checked intent not the expected one", expectedIntent.getComponent(), actualIntent.getComponent());
+
+ List logs = ShadowLog.getLogs();
+ ShadowLog.LogItem lastLog = logs.get(logs.size()-1);
+
+ //Note: Checking log is the only way I've found to check that the service stopped as expected
+ Assert.assertEquals("Last log isn't the one expected", "Initialization hasn't been done", lastLog.msg);
+ //Assert.assertTrue(logs.contains()); //@TODO how to assert that logs doesn't contain the expecteed message ?
+
+ //tearDown - Remove DB if it had been created
+ mService.deleteDatabase(DbHelper.DATABASE_NAME);
+ }
+}
\ No newline at end of file
diff --git a/app/src/test/java/foundation/e/drive/services/OperationManagerServiceTest.java b/app/src/test/java/foundation/e/drive/services/OperationManagerServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0a2fb8f73f1790b30fd3d68758ec7f818d3d7c35
--- /dev/null
+++ b/app/src/test/java/foundation/e/drive/services/OperationManagerServiceTest.java
@@ -0,0 +1,108 @@
+package foundation.e.drive.services;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.job.JobScheduler;
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+
+import com.owncloud.android.lib.resources.files.model.RemoteFile;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowLog;
+
+import java.util.List;
+
+import foundation.e.drive.TestUtils;
+import foundation.e.drive.database.DbHelper;
+import foundation.e.drive.models.SyncedFileState;
+import foundation.e.drive.operations.DownloadFileOperation;
+import foundation.e.drive.utils.AppConstants;
+
+
+public class OperationManagerServiceTest extends AbstractServiceIT{
+
+ public OperationManagerServiceTest(){
+ mServiceController = Robolectric.buildService(OperationManagerService.class);
+ mService = mServiceController.get();
+ context = RuntimeEnvironment.application;
+ accountManager = AccountManager.get(context);
+ jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+ contentResolver = context.getContentResolver();
+ sharedPreferences = context.getSharedPreferences( AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE);
+ connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ dbHelper = new DbHelper(context);
+ }
+
+
+ /**
+ * Check that the service stop quickly if no intent is provided
+ */
+ @Test
+ public void noIntent_shouldStop(){
+ mServiceController.create();
+ mService.onStartCommand(null,0, 0);
+
+ List logs = ShadowLog.getLogs();
+ ShadowLog.LogItem lastLog = logs.get(logs.size()-2);
+
+ Assert.assertEquals("Expected last log was: 'intent was null, flags=0 bits=0' but got:"+lastLog.msg, "intent was null, flags=0 bits=0", lastLog.msg);
+ }
+
+
+ /**
+ * Start the service with an intent that doesn't contains list of extra data
+ * (meaning no account and no synchronisation to perform)
+ */
+ @Test
+ public void intentWithoutExtras_shouldStop(){
+ mServiceController.create();
+ mService.onStartCommand(new Intent(), 0, 0);
+
+ List logs = ShadowLog.getLogs();
+ ShadowLog.LogItem lastLog = logs.get(logs.size()-1);
+
+ Assert.assertEquals("Expected last log was: 'Intent's extras is null.' but got:"+lastLog.msg, "Intent's extras is null.", lastLog.msg);
+ }
+
+
+ /**
+ * Start the OperationmanagerService with File to upload but no account provided
+ * in the intent.
+ * Failure is expected
+ */
+ @Test
+ public void noAccount_shouldFail(){
+ prepareValidAccount();
+ final Account account = TestUtils.getValidAccount();
+ final Intent intent = new Intent("dummyAction");
+
+ intent.putExtra("0",
+ new DownloadFileOperation(
+ new RemoteFile("/eDrive-test/coco.txt"),
+ new SyncedFileState(3, "coco.txt", "/tmp/eDrive-test/", "/eDrive-test/coco.txt","", -1, 1, true )
+ )
+ );
+
+
+ intent.putExtra("account", account);
+
+ final boolean accountRemoved = accountManager.removeAccountExplicitly(account);
+ Assert.assertTrue("Account removal should return true but returned false", accountRemoved);
+
+ mServiceController.create();
+ mService.onStartCommand(intent, 0,0);
+
+ List logs = ShadowLog.getLogs();
+ ShadowLog.LogItem lastLog = logs.get(logs.size()-1);
+ Assert.assertEquals("Expected last log was: 'No Client, Can't Work!' but got:"+lastLog.msg, "No Client, Can't Work!", lastLog.msg);
+
+ }
+
+
+}
diff --git a/build.gradle b/build.gradle
index 88560b47dc768e6a7cbefe8c44a977b32623aa94..3378f0cd90a587b6f781e45f221ba00f97f51ebf 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.1.3'
+ classpath 'com.android.tools.build:gradle:4.1.3'
// NOTE: Do not place your application dependencies here; they belong
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 54f9e46602f2b5e51d1294b2d243fc60ca32c500..46b275d78fb233a28426185786ef96bde557b078 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
diff --git a/nextcloud-android-lib b/nextcloud-android-lib
index 880099c889253f30969b81c5e07750f070bfb65c..353568a74c0708496b36614b3ff69b9fafe9af0b 160000
--- a/nextcloud-android-lib
+++ b/nextcloud-android-lib
@@ -1 +1 @@
-Subproject commit 880099c889253f30969b81c5e07750f070bfb65c
+Subproject commit 353568a74c0708496b36614b3ff69b9fafe9af0b