/*
*
* Nextcloud Android client application
*
* @author Tobias Kaminsky
* Copyright (C) 2020 Tobias Kaminsky
* Copyright (C) 2020 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package com.owncloud.android.datamodel;
import android.content.ContentValues;
import com.owncloud.android.AbstractOnServerIT;
import com.owncloud.android.db.ProviderMeta;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.resources.files.CreateFolderRemoteOperation;
import com.owncloud.android.lib.resources.files.SearchRemoteOperation;
import com.owncloud.android.lib.resources.files.UploadFileRemoteOperation;
import com.owncloud.android.lib.resources.files.model.RemoteFile;
import com.owncloud.android.lib.resources.status.CapabilityBooleanType;
import com.owncloud.android.lib.resources.status.OCCapability;
import com.owncloud.android.operations.RefreshFolderOperation;
import com.owncloud.android.utils.FileStorageUtils;
import junit.framework.TestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static com.owncloud.android.lib.resources.files.SearchRemoteOperation.SearchType.GALLERY_SEARCH;
import static com.owncloud.android.lib.resources.files.SearchRemoteOperation.SearchType.PHOTO_SEARCH;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
abstract public class FileDataStorageManagerIT extends AbstractOnServerIT {
protected FileDataStorageManager sut;
@Before
public void before() {
// make sure everything is removed
sut.deleteAllFiles();
sut.deleteVirtuals(VirtualFolderType.GALLERY);
assertEquals(0, sut.getAllFiles().size());
}
@After
public void after() {
super.after();
sut.deleteAllFiles();
sut.deleteVirtuals(VirtualFolderType.GALLERY);
}
@Test
public void simpleTest() {
OCFile file = sut.getFileByDecryptedRemotePath("/");
assertNotNull(file);
assertTrue(file.fileExists());
assertNull(sut.getFileByDecryptedRemotePath("/123123"));
}
@Test
public void getAllFiles_NoAvailable() {
assertEquals(0, sut.getAllFiles().size());
}
@Test
public void testFolderContent() throws IOException {
assertEquals(0, sut.getAllFiles().size());
assertTrue(new CreateFolderRemoteOperation("/1/1/", true).execute(client).isSuccess());
assertTrue(new CreateFolderRemoteOperation("/1/2/", true).execute(client).isSuccess());
assertTrue(new UploadFileRemoteOperation(getDummyFile("/chunkedFile.txt").getAbsolutePath(),
"/1/1/chunkedFile.txt",
"text/plain",
String.valueOf(System.currentTimeMillis() / 1000))
.execute(client).isSuccess());
assertTrue(new UploadFileRemoteOperation(getDummyFile("/chunkedFile.txt").getAbsolutePath(),
"/1/1/chunkedFile2.txt",
"text/plain",
String.valueOf(System.currentTimeMillis() / 1000))
.execute(client).isSuccess());
File imageFile = getFile("imageFile.png");
assertTrue(new UploadFileRemoteOperation(imageFile.getAbsolutePath(),
"/1/1/imageFile.png",
"image/png",
String.valueOf(System.currentTimeMillis() / 1000))
.execute(client).isSuccess());
// sync
assertNull(sut.getFileByDecryptedRemotePath("/1/1/"));
assertTrue(new RefreshFolderOperation(sut.getFileByDecryptedRemotePath("/"),
System.currentTimeMillis() / 1000,
false,
false,
sut,
user,
targetContext).execute(client).isSuccess());
assertTrue(new RefreshFolderOperation(sut.getFileByDecryptedRemotePath("/1/"),
System.currentTimeMillis() / 1000,
false,
false,
sut,
user,
targetContext).execute(client).isSuccess());
assertTrue(new RefreshFolderOperation(sut.getFileByDecryptedRemotePath("/1/1/"),
System.currentTimeMillis() / 1000,
false,
false,
sut,
user,
targetContext).execute(client).isSuccess());
assertEquals(3, sut.getFolderContent(sut.getFileByDecryptedRemotePath("/1/1/"), false).size());
}
/**
* This test creates an image, does a photo search (now returned image is not yet in file hierarchy), then root
* folder is refreshed and it is verified that the same image file is used in database
*/
@Test
public void testPhotoSearch() throws IOException {
String remotePath = "/imageFile.png";
VirtualFolderType virtualType = VirtualFolderType.GALLERY;
assertEquals(0, sut.getFolderContent(sut.getFileByDecryptedRemotePath("/"), false).size());
assertEquals(1, sut.getAllFiles().size());
File imageFile = getFile("imageFile.png");
assertTrue(new UploadFileRemoteOperation(imageFile.getAbsolutePath(),
remotePath,
"image/png",
String.valueOf(System.currentTimeMillis() / 1000))
.execute(client).isSuccess());
assertNull(sut.getFileByDecryptedRemotePath(remotePath));
// search
SearchRemoteOperation searchRemoteOperation = new SearchRemoteOperation("image/%",
PHOTO_SEARCH,
false);
RemoteOperationResult> searchResult = searchRemoteOperation.execute(client);
TestCase.assertTrue(searchResult.isSuccess());
TestCase.assertEquals(1, searchResult.getResultData().size());
OCFile ocFile = FileStorageUtils.fillOCFile(searchResult.getResultData().get(0));
sut.saveFile(ocFile);
List contentValues = new ArrayList<>();
ContentValues cv = new ContentValues();
cv.put(ProviderMeta.ProviderTableMeta.VIRTUAL_TYPE, virtualType.toString());
cv.put(ProviderMeta.ProviderTableMeta.VIRTUAL_OCFILE_ID, ocFile.getFileId());
contentValues.add(cv);
sut.saveVirtuals(contentValues);
assertEquals(remotePath, ocFile.getRemotePath());
assertEquals(0, sut.getFolderContent(sut.getFileByDecryptedRemotePath("/"), false).size());
assertEquals(1, sut.getVirtualFolderContent(virtualType, false).size());
assertEquals(2, sut.getAllFiles().size());
// update root
assertTrue(new RefreshFolderOperation(sut.getFileByDecryptedRemotePath("/"),
System.currentTimeMillis() / 1000,
false,
false,
sut,
user,
targetContext).execute(client).isSuccess());
assertEquals(1, sut.getFolderContent(sut.getFileByDecryptedRemotePath("/"), false).size());
assertEquals(1, sut.getVirtualFolderContent(virtualType, false).size());
assertEquals(2, sut.getAllFiles().size());
assertEquals(sut.getVirtualFolderContent(virtualType, false).get(0),
sut.getFolderContent(sut.getFileByDecryptedRemotePath("/"), false).get(0));
}
/**
* This test creates an image and a video, does a gallery search (now returned image and video is not yet in file
* hierarchy), then root folder is refreshed and it is verified that the same image file is used in database
*/
@Test
public void testGallerySearch() throws IOException {
sut = new FileDataStorageManager(account,
targetContext
.getContentResolver()
.acquireContentProviderClient(ProviderMeta.ProviderTableMeta.CONTENT_URI)
);
String imagePath = "/imageFile.png";
VirtualFolderType virtualType = VirtualFolderType.GALLERY;
assertEquals(0, sut.getFolderContent(sut.getFileByDecryptedRemotePath("/"), false).size());
assertEquals(1, sut.getAllFiles().size());
File imageFile = getFile("imageFile.png");
assertTrue(new UploadFileRemoteOperation(imageFile.getAbsolutePath(),
imagePath,
"image/png",
String.valueOf((System.currentTimeMillis() - 10000) / 1000))
.execute(client).isSuccess());
// Check that file does not yet exist in local database
assertNull(sut.getFileByDecryptedRemotePath(imagePath));
String videoPath = "/videoFile.mp4";
File videoFile = getFile("videoFile.mp4");
assertTrue(new UploadFileRemoteOperation(videoFile.getAbsolutePath(),
videoPath,
"video/mpeg",
String.valueOf((System.currentTimeMillis() + 10000) / 1000))
.execute(client).isSuccess());
// Check that file does not yet exist in local database
assertNull(sut.getFileByDecryptedRemotePath(videoPath));
// search
SearchRemoteOperation searchRemoteOperation = new SearchRemoteOperation("",
GALLERY_SEARCH,
false);
RemoteOperationResult> searchResult = searchRemoteOperation.execute(client);
TestCase.assertTrue(searchResult.isSuccess());
TestCase.assertEquals(2, searchResult.getResultData().size());
// newest file must be video path (as sorted by recently modified)
OCFile ocFile = FileStorageUtils.fillOCFile( searchResult.getResultData().get(0));
sut.saveFile(ocFile);
assertEquals(videoPath, ocFile.getRemotePath());
List contentValues = new ArrayList<>();
ContentValues cv = new ContentValues();
cv.put(ProviderMeta.ProviderTableMeta.VIRTUAL_TYPE, virtualType.toString());
cv.put(ProviderMeta.ProviderTableMeta.VIRTUAL_OCFILE_ID, ocFile.getFileId());
contentValues.add(cv);
// second is image file, as older
OCFile ocFile2 = FileStorageUtils.fillOCFile(searchResult.getResultData().get(1));
sut.saveFile(ocFile2);
assertEquals(imagePath, ocFile2.getRemotePath());
ContentValues cv2 = new ContentValues();
cv2.put(ProviderMeta.ProviderTableMeta.VIRTUAL_TYPE, virtualType.toString());
cv2.put(ProviderMeta.ProviderTableMeta.VIRTUAL_OCFILE_ID, ocFile2.getFileId());
contentValues.add(cv2);
sut.saveVirtuals(contentValues);
assertEquals(0, sut.getFolderContent(sut.getFileByDecryptedRemotePath("/"), false).size());
assertEquals(2, sut.getVirtualFolderContent(virtualType, false).size());
assertEquals(3, sut.getAllFiles().size());
// update root
assertTrue(new RefreshFolderOperation(sut.getFileByDecryptedRemotePath("/"),
System.currentTimeMillis() / 1000,
false,
false,
sut,
user,
targetContext).execute(client).isSuccess());
assertEquals(2, sut.getFolderContent(sut.getFileByDecryptedRemotePath("/"), false).size());
assertEquals(2, sut.getVirtualFolderContent(virtualType, false).size());
assertEquals(3, sut.getAllFiles().size());
assertEquals(sut.getVirtualFolderContent(virtualType, false).get(0),
sut.getFolderContent(sut.getFileByDecryptedRemotePath("/"), false).get(0));
}
@Test
public void testSaveNewFile() {
assertTrue(new CreateFolderRemoteOperation("/1/1/", true).execute(client).isSuccess());
assertTrue(new RefreshFolderOperation(sut.getFileByDecryptedRemotePath("/"),
System.currentTimeMillis() / 1000,
false,
false,
sut,
user,
targetContext).execute(client).isSuccess());
assertTrue(new RefreshFolderOperation(sut.getFileByDecryptedRemotePath("/1/"),
System.currentTimeMillis() / 1000,
false,
false,
sut,
user,
targetContext).execute(client).isSuccess());
assertTrue(new RefreshFolderOperation(sut.getFileByDecryptedRemotePath("/1/1/"),
System.currentTimeMillis() / 1000,
false,
false,
sut,
user,
targetContext).execute(client).isSuccess());
OCFile newFile = new OCFile("/1/1/1.txt");
newFile.setRemoteId("123");
sut.saveNewFile(newFile);
}
@Test(expected = IllegalArgumentException.class)
public void testSaveNewFile_NonExistingParent() {
assertTrue(new CreateFolderRemoteOperation("/1/1/", true).execute(client).isSuccess());
OCFile newFile = new OCFile("/1/1/1.txt");
sut.saveNewFile(newFile);
}
@Test
public void testOCCapability() {
OCCapability capability = new OCCapability();
capability.setUserStatus(CapabilityBooleanType.TRUE);
sut.saveCapabilities(capability);
OCCapability newCapability = sut.getCapability(user);
assertEquals(capability.getUserStatus(), newCapability.getUserStatus());
}
}