|
| 1 | +/* |
| 2 | + * Nextcloud Android client application |
| 3 | + * |
| 4 | + * @author Tobias Kaminsky |
| 5 | + * Copyright (C) 2022 Tobias Kaminsky |
| 6 | + * Copyright (C) 2022 Nextcloud GmbH |
| 7 | + * |
| 8 | + * This program is free software: you can redistribute it and/or modify |
| 9 | + * it under the terms of the GNU Affero General Public License as published by |
| 10 | + * the Free Software Foundation, either version 3 of the License, or |
| 11 | + * (at your option) any later version. |
| 12 | + * |
| 13 | + * This program is distributed in the hope that it will be useful, |
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | + * GNU Affero General Public License for more details. |
| 17 | + * |
| 18 | + * You should have received a copy of the GNU Affero General Public License |
| 19 | + * along with this program. If not, see <https://www.gnu.org/licenses/>. |
| 20 | + * |
| 21 | + */ |
| 22 | + |
| 23 | +package com.owncloud.android |
| 24 | + |
| 25 | +import at.bitfire.dav4jvm.DavResource |
| 26 | +import at.bitfire.dav4jvm.PropertyRegistry |
| 27 | +import at.bitfire.dav4jvm.Response |
| 28 | +import at.bitfire.dav4jvm.property.CreationDate |
| 29 | +import at.bitfire.dav4jvm.property.GetContentType |
| 30 | +import at.bitfire.dav4jvm.property.GetLastModified |
| 31 | +import at.bitfire.dav4jvm.property.ResourceType |
| 32 | +import com.nextcloud.common.NextcloudAuthenticator |
| 33 | +import com.nextcloud.talk.components.filebrowser.models.properties.OCId |
| 34 | +import com.nextcloud.talk.components.filebrowser.models.properties.OCOwnerDisplayName |
| 35 | +import com.nextcloud.talk.components.filebrowser.models.properties.OCOwnerId |
| 36 | +import com.nextcloud.talk.components.filebrowser.models.properties.OCSize |
| 37 | +import com.owncloud.android.lib.common.network.WebdavUtils |
| 38 | +import com.owncloud.android.lib.common.utils.WebDavFileUtils |
| 39 | +import com.owncloud.android.lib.resources.files.CreateFolderRemoteOperation |
| 40 | +import com.owncloud.android.lib.resources.files.ReadFolderRemoteOperation |
| 41 | +import com.owncloud.android.lib.resources.files.SearchRemoteOperation |
| 42 | +import com.owncloud.android.lib.resources.files.ToggleFavoriteRemoteOperation |
| 43 | +import com.owncloud.android.lib.resources.files.UploadFileRemoteOperation |
| 44 | +import com.owncloud.android.lib.resources.files.model.RemoteFile |
| 45 | +import com.owncloud.android.lib.resources.files.webdav.NCEtag |
| 46 | +import com.owncloud.android.lib.resources.files.webdav.NCFavorite |
| 47 | +import com.owncloud.android.lib.resources.files.webdav.NCMountType |
| 48 | +import com.owncloud.android.lib.resources.files.webdav.Permissions |
| 49 | +import com.owncloud.android.lib.resources.status.OCCapability |
| 50 | +import okhttp3.HttpUrl.Companion.toHttpUrl |
| 51 | +import org.apache.jackrabbit.webdav.DavConstants |
| 52 | +import org.junit.Assert.assertEquals |
| 53 | +import org.junit.Assert.assertTrue |
| 54 | +import org.junit.Test |
| 55 | +import java.io.IOException |
| 56 | + |
| 57 | +class Dav4JVMtest : AbstractIT() { |
| 58 | + @Test |
| 59 | + @Throws(IOException::class) |
| 60 | + fun singlePropfind() { |
| 61 | + val path = "/testFolder/" |
| 62 | + |
| 63 | + // create folder |
| 64 | + CreateFolderRemoteOperation( |
| 65 | + path, |
| 66 | + true |
| 67 | + ).execute(client).isSuccess |
| 68 | + |
| 69 | + // verify folder |
| 70 | + assertTrue(ReadFolderRemoteOperation(path).execute(client).isSuccess) |
| 71 | + |
| 72 | + // add favorite |
| 73 | + assertTrue(ToggleFavoriteRemoteOperation(true, path).execute(client).isSuccess) |
| 74 | + |
| 75 | + // do old read folder operation to compare data against it |
| 76 | + val result = ReadFolderRemoteOperation(path).execute(client).data as List<RemoteFile> |
| 77 | + val oldRemoteFile = result[0] |
| 78 | + |
| 79 | + // new |
| 80 | + val httpUrl = (nextcloudClient.filesDavUri.toString() + path).toHttpUrl() |
| 81 | + |
| 82 | + var davResponse: Response? = null |
| 83 | + |
| 84 | + val memberElements: MutableList<Response> = ArrayList() |
| 85 | + var rootElement: Response? = null |
| 86 | + |
| 87 | + // disable redirect |
| 88 | + val client = nextcloudClient.client |
| 89 | + .newBuilder() |
| 90 | + .followRedirects(false) |
| 91 | + .authenticator(NextcloudAuthenticator(nextcloudClient.credentials, "Authorization")) |
| 92 | + .build() |
| 93 | + |
| 94 | + // register custom property |
| 95 | + registerProperties() |
| 96 | + |
| 97 | + DavResource( |
| 98 | + client, |
| 99 | + httpUrl |
| 100 | + ) |
| 101 | + |
| 102 | + DavResource( |
| 103 | + client, |
| 104 | + httpUrl |
| 105 | + ).propfind( |
| 106 | + DavConstants.DEPTH_1, |
| 107 | + CreationDate.NAME, |
| 108 | + NCFavorite.NAME, |
| 109 | + NCEtag.NAME, |
| 110 | + GetLastModified.NAME, |
| 111 | + GetContentType.NAME, |
| 112 | + ResourceType.NAME, |
| 113 | + Permissions.NAME, |
| 114 | + OCId.NAME, |
| 115 | + OCSize.NAME, |
| 116 | + NCMountType.NAME, |
| 117 | + OCOwnerId.NAME, |
| 118 | + OCOwnerDisplayName.NAME |
| 119 | + ) { response: Response, hrefRelation: Response.HrefRelation? -> |
| 120 | + davResponse = response |
| 121 | + when (hrefRelation) { |
| 122 | + Response.HrefRelation.MEMBER -> memberElements.add(response) |
| 123 | + Response.HrefRelation.SELF -> rootElement = response |
| 124 | + Response.HrefRelation.OTHER -> {} |
| 125 | + else -> {} |
| 126 | + } |
| 127 | + } |
| 128 | + |
| 129 | + assertTrue(davResponse?.isSuccess() == true) |
| 130 | + assertTrue(rootElement != null) |
| 131 | + assertEquals(0, memberElements.size) |
| 132 | + |
| 133 | + val remoteFile = WebDavFileUtils().parseResponse(rootElement, nextcloudClient.filesDavUri) |
| 134 | + |
| 135 | + val date = davResponse?.get(CreationDate::class.java) |
| 136 | + assertEquals( |
| 137 | + oldRemoteFile.creationTimestamp, |
| 138 | + (WebdavUtils.parseResponseDate(date?.creationDate)?.time ?: 0) / 1000 |
| 139 | + ) |
| 140 | + |
| 141 | + assertTrue(oldRemoteFile.isFavorite) |
| 142 | + val favorite = davResponse?.get(NCFavorite::class.java) |
| 143 | + assertTrue(favorite?.isOcFavorite == true) |
| 144 | + |
| 145 | + assertEquals(oldRemoteFile.remotePath, remoteFile.remotePath) |
| 146 | + assertEquals(oldRemoteFile.mimeType, remoteFile.mimeType) |
| 147 | + assertEquals(oldRemoteFile.length, remoteFile.length) |
| 148 | + assertEquals(oldRemoteFile.creationTimestamp, remoteFile.creationTimestamp) |
| 149 | + // assertEquals(oldRemoteFile.modifiedTimestamp, remoteFile.modifiedTimestamp) |
| 150 | + assertEquals(oldRemoteFile.uploadTimestamp, remoteFile.uploadTimestamp) |
| 151 | + assertEquals(oldRemoteFile.etag, remoteFile.etag) |
| 152 | + assertEquals(oldRemoteFile.permissions, remoteFile.permissions) |
| 153 | + assertEquals(oldRemoteFile.remoteId, remoteFile.remoteId) |
| 154 | + assertEquals(oldRemoteFile.size, remoteFile.size) |
| 155 | + assertEquals(oldRemoteFile.isFavorite, remoteFile.isFavorite) |
| 156 | + assertEquals(oldRemoteFile.isEncrypted, remoteFile.isEncrypted) |
| 157 | + assertEquals(oldRemoteFile.mountType, remoteFile.mountType) |
| 158 | + assertEquals(oldRemoteFile.ownerId, remoteFile.ownerId) |
| 159 | + assertEquals(oldRemoteFile.ownerDisplayName, remoteFile.ownerDisplayName) |
| 160 | + assertEquals(oldRemoteFile.unreadCommentsCount, remoteFile.unreadCommentsCount) |
| 161 | + assertEquals(oldRemoteFile.isHasPreview, remoteFile.isHasPreview) |
| 162 | + assertEquals(oldRemoteFile.note, remoteFile.note) |
| 163 | + assertEquals(oldRemoteFile.sharees, remoteFile.sharees) |
| 164 | + assertEquals(oldRemoteFile.richWorkspace, remoteFile.richWorkspace) |
| 165 | + assertEquals(oldRemoteFile.isLocked, remoteFile.isLocked) |
| 166 | + assertEquals(oldRemoteFile.lockType, remoteFile.lockType) |
| 167 | + assertEquals(oldRemoteFile.lockOwner, remoteFile.lockOwner) |
| 168 | + assertEquals(oldRemoteFile.lockOwnerDisplayName, remoteFile.lockOwnerDisplayName) |
| 169 | + assertEquals(oldRemoteFile.lockTimestamp, remoteFile.lockTimestamp) |
| 170 | + assertEquals(oldRemoteFile.lockOwnerEditor, remoteFile.lockOwnerEditor) |
| 171 | + assertEquals(oldRemoteFile.lockTimeout, remoteFile.lockTimeout) |
| 172 | + assertEquals(oldRemoteFile.lockToken, remoteFile.lockToken) |
| 173 | + assertEquals(oldRemoteFile.localId, remoteFile.localId) |
| 174 | + |
| 175 | + // assertEquals(oldRemoteFile, remoteFile) |
| 176 | + } |
| 177 | + |
| 178 | + @Test |
| 179 | + fun search() { |
| 180 | + val path = "/testFolder/" |
| 181 | + |
| 182 | + // create folder |
| 183 | + // assertTrue( |
| 184 | + CreateFolderRemoteOperation( |
| 185 | + path, |
| 186 | + true |
| 187 | + ).execute(client).isSuccess |
| 188 | + // ) |
| 189 | + |
| 190 | + // create file |
| 191 | + val filePath = createFile("text") |
| 192 | + val remotePath = "/test.md" |
| 193 | + |
| 194 | + assertTrue( |
| 195 | + UploadFileRemoteOperation( |
| 196 | + filePath, |
| 197 | + remotePath, |
| 198 | + "text/markdown", |
| 199 | + "", |
| 200 | + RANDOM_MTIME, |
| 201 | + System.currentTimeMillis(), |
| 202 | + true |
| 203 | + ).execute(client).isSuccess |
| 204 | + ) |
| 205 | + |
| 206 | + registerProperties() |
| 207 | + |
| 208 | + var ror = SearchRemoteOperation( |
| 209 | + "test", |
| 210 | + SearchRemoteOperation.SearchType.FILE_SEARCH, |
| 211 | + false, |
| 212 | + OCCapability(23, 0, 0) |
| 213 | + ).execute( |
| 214 | + client |
| 215 | + ) |
| 216 | + |
| 217 | + assertTrue(ror.isSuccess) |
| 218 | + assertEquals(2, ror.resultData.size) |
| 219 | + |
| 220 | + val oldRemoteFile = ror.resultData[0] |
| 221 | + assertEquals(path, oldRemoteFile.remotePath) |
| 222 | + |
| 223 | + ror = SearchRemoteOperation( |
| 224 | + "test", |
| 225 | + SearchRemoteOperation.SearchType.FILE_SEARCH, |
| 226 | + false, |
| 227 | + OCCapability(23, 0, 0) |
| 228 | + ).execute( |
| 229 | + nextcloudClient |
| 230 | + ) |
| 231 | + |
| 232 | + assertTrue(ror.isSuccess) |
| 233 | + assertEquals(2, ror.resultData.size) |
| 234 | + |
| 235 | + val remoteFile = ror.resultData[0] |
| 236 | + assertEquals(path, remoteFile.remotePath) |
| 237 | + |
| 238 | + assertEquals(oldRemoteFile.remoteId, remoteFile.remoteId) |
| 239 | + } |
| 240 | + |
| 241 | + @Test |
| 242 | + fun proppatch() { |
| 243 | + assertTrue(false) |
| 244 | + } |
| 245 | + |
| 246 | + private fun registerProperties() { |
| 247 | + val list = listOf( |
| 248 | + NCFavorite.Factory(), |
| 249 | + NCEtag.Factory(), |
| 250 | + Permissions.Factory(), |
| 251 | + OCId.Factory(), |
| 252 | + OCSize.Factory(), |
| 253 | + NCMountType.Factory(), |
| 254 | + OCOwnerId.Factory(), |
| 255 | + OCOwnerDisplayName.Factory() |
| 256 | + ) |
| 257 | + |
| 258 | + PropertyRegistry.register(list) |
| 259 | + } |
| 260 | +} |
0 commit comments