Skip to content

Commit 0fe738a

Browse files
use dav4jvm search and proppatch
Signed-off-by: tobiasKaminsky <[email protected]>
1 parent 12982fe commit 0fe738a

29 files changed

+1760
-116
lines changed

dav4jvm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit c61e4b0c80a5a8de1df99b4997445bb323d3ea3d

library/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ configurations {
5050
dependencies {
5151
implementation 'org.apache.jackrabbit:jackrabbit-webdav:2.13.5'
5252
api 'com.squareup.okhttp3:okhttp:5.0.0-alpha.10'
53-
implementation 'com.gitlab.bitfireAT:dav4jvm:2.1.3' // in transition phase, we use old and new libs
53+
implementation 'com.github.bitfireAT:dav4jvm:2.2' // in transition phase, we use old and new libs
5454
implementation group: 'com.google.code.gson', name: 'gson', version: '2.10'
5555
implementation 'androidx.annotation:annotation:1.5.0'
5656
compileOnly 'com.google.code.findbugs:annotations:3.0.1u2'

library/src/androidTest/java/com/owncloud/android/AbstractIT.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ public static void beforeAll() throws InterruptedException,
121121
String userId = loginName; // for test same as userId
122122
String credentials = Credentials.basic(loginName, password);
123123
nextcloudClient = new NextcloudClient(url, userId, credentials, context);
124+
nextcloudClient.setUserId(userId);
124125

125126
waitForServer(client, url);
126127
testConnection();
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
/* Nextcloud Android Library is available under MIT license
2+
*
3+
* @author Tobias Kaminsky
4+
* Copyright (C) 2022 Tobias Kaminsky
5+
* Copyright (C) 2022 Nextcloud GmbH
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21+
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22+
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*
26+
*/
27+
28+
package com.owncloud.android
29+
30+
import at.bitfire.dav4jvm.DavResource
31+
import at.bitfire.dav4jvm.Response
32+
import at.bitfire.dav4jvm.property.CreationDate
33+
import com.nextcloud.common.NextcloudAuthenticator
34+
import com.owncloud.android.lib.common.network.WebdavUtils
35+
import com.owncloud.android.lib.common.utils.WebDavFileUtils
36+
import com.owncloud.android.lib.resources.files.CreateFolderRemoteOperation
37+
import com.owncloud.android.lib.resources.files.ReadFolderRemoteOperation
38+
import com.owncloud.android.lib.resources.files.SearchRemoteOperation
39+
import com.owncloud.android.lib.resources.files.ToggleFavoriteRemoteOperation
40+
import com.owncloud.android.lib.resources.files.UploadFileRemoteOperation
41+
import com.owncloud.android.lib.resources.files.model.RemoteFile
42+
import com.owncloud.android.lib.resources.files.webdav.NCFavorite
43+
import com.owncloud.android.lib.resources.shares.CreateShareRemoteOperation
44+
import com.owncloud.android.lib.resources.shares.OCShare
45+
import com.owncloud.android.lib.resources.shares.ShareType
46+
import com.owncloud.android.lib.resources.status.OCCapability
47+
import okhttp3.HttpUrl.Companion.toHttpUrl
48+
import org.apache.jackrabbit.webdav.DavConstants
49+
import org.junit.Assert.assertEquals
50+
import org.junit.Assert.assertTrue
51+
import org.junit.Test
52+
import java.io.IOException
53+
54+
/*
55+
can be removed after fully switching to dav4jvm as other tests should cover it
56+
*/
57+
class Dav4JVM : 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+
// share it
76+
assertTrue(
77+
CreateShareRemoteOperation(
78+
path,
79+
ShareType.USER,
80+
"admin",
81+
false,
82+
"",
83+
OCShare.MAXIMUM_PERMISSIONS_FOR_FOLDER,
84+
true
85+
).execute(client)
86+
.isSuccess
87+
)
88+
89+
// do old read folder operation to compare data against it
90+
val result = ReadFolderRemoteOperation(path).execute(client).data as List<RemoteFile>
91+
val oldRemoteFile = result[0]
92+
93+
// new
94+
val httpUrl = (nextcloudClient.filesDavUri.toString() + path).toHttpUrl()
95+
96+
var davResponse: Response? = null
97+
98+
val memberElements: MutableList<Response> = ArrayList()
99+
var rootElement: Response? = null
100+
101+
// disable redirect
102+
val client = nextcloudClient.client
103+
.newBuilder()
104+
.followRedirects(false)
105+
.authenticator(NextcloudAuthenticator(nextcloudClient.credentials, "Authorization"))
106+
.build()
107+
108+
// register custom property
109+
WebdavUtils.registerCustomFactories()
110+
111+
DavResource(client, httpUrl)
112+
.propfind(
113+
DavConstants.DEPTH_1,
114+
*WebdavUtils.getAllPropertiesList()
115+
) { response: Response, hrefRelation: Response.HrefRelation? ->
116+
davResponse = response
117+
when (hrefRelation) {
118+
Response.HrefRelation.MEMBER -> memberElements.add(response)
119+
Response.HrefRelation.SELF -> rootElement = response
120+
Response.HrefRelation.OTHER -> {}
121+
else -> {}
122+
}
123+
}
124+
125+
assertTrue(davResponse?.isSuccess() == true)
126+
assertTrue(rootElement != null)
127+
assertEquals(0, memberElements.size)
128+
129+
val remoteFile = WebDavFileUtils().parseResponse(rootElement, nextcloudClient.filesDavUri)
130+
131+
val date = davResponse?.get(CreationDate::class.java)
132+
assertEquals(
133+
oldRemoteFile.creationTimestamp,
134+
(WebdavUtils.parseResponseDate(date?.creationDate)?.time ?: 0) / 1000
135+
)
136+
137+
assertTrue(oldRemoteFile.isFavorite)
138+
val favorite = davResponse?.get(NCFavorite::class.java)
139+
assertTrue(favorite?.isOcFavorite == true)
140+
141+
assertEquals(oldRemoteFile.remotePath, remoteFile.remotePath)
142+
assertEquals(oldRemoteFile.mimeType, remoteFile.mimeType)
143+
assertEquals(oldRemoteFile.length, remoteFile.length)
144+
assertEquals(oldRemoteFile.creationTimestamp, remoteFile.creationTimestamp)
145+
// assertEquals(oldRemoteFile.modifiedTimestamp, remoteFile.modifiedTimestamp)
146+
assertEquals(oldRemoteFile.uploadTimestamp, remoteFile.uploadTimestamp)
147+
assertEquals(oldRemoteFile.etag, remoteFile.etag)
148+
assertEquals(oldRemoteFile.permissions, remoteFile.permissions)
149+
assertEquals(oldRemoteFile.remoteId, remoteFile.remoteId)
150+
assertEquals(oldRemoteFile.size, remoteFile.size)
151+
assertEquals(oldRemoteFile.isFavorite, remoteFile.isFavorite)
152+
assertEquals(oldRemoteFile.isEncrypted, remoteFile.isEncrypted)
153+
assertEquals(oldRemoteFile.mountType, remoteFile.mountType)
154+
assertEquals(oldRemoteFile.ownerId, remoteFile.ownerId)
155+
assertEquals(oldRemoteFile.ownerDisplayName, remoteFile.ownerDisplayName)
156+
assertEquals(oldRemoteFile.unreadCommentsCount, remoteFile.unreadCommentsCount)
157+
assertEquals(oldRemoteFile.isHasPreview, remoteFile.isHasPreview)
158+
assertEquals(oldRemoteFile.note, remoteFile.note)
159+
assertEquals(oldRemoteFile.sharees.size, remoteFile.sharees.size)
160+
assertEquals(oldRemoteFile.richWorkspace, remoteFile.richWorkspace)
161+
assertEquals(oldRemoteFile.isLocked, remoteFile.isLocked)
162+
assertEquals(oldRemoteFile.lockType, remoteFile.lockType)
163+
assertEquals(oldRemoteFile.lockOwner, remoteFile.lockOwner)
164+
assertEquals(oldRemoteFile.lockOwnerDisplayName, remoteFile.lockOwnerDisplayName)
165+
assertEquals(oldRemoteFile.lockTimestamp, remoteFile.lockTimestamp)
166+
assertEquals(oldRemoteFile.lockOwnerEditor, remoteFile.lockOwnerEditor)
167+
assertEquals(oldRemoteFile.lockTimeout, remoteFile.lockTimeout)
168+
assertEquals(oldRemoteFile.lockToken, remoteFile.lockToken)
169+
assertEquals(oldRemoteFile.localId, remoteFile.localId)
170+
}
171+
172+
@Test
173+
fun search() {
174+
val path = "/testFolder/"
175+
176+
// create folder
177+
assertTrue(
178+
CreateFolderRemoteOperation(
179+
path,
180+
true
181+
).execute(client).isSuccess
182+
)
183+
184+
// create file
185+
val filePath = createFile("text")
186+
val remotePath = "/test.md"
187+
188+
assertTrue(
189+
UploadFileRemoteOperation(
190+
filePath,
191+
remotePath,
192+
"text/markdown",
193+
"",
194+
RANDOM_MTIME,
195+
System.currentTimeMillis(),
196+
true
197+
).execute(client).isSuccess
198+
)
199+
200+
WebdavUtils.registerCustomFactories()
201+
202+
var ror = SearchRemoteOperation(
203+
"test",
204+
SearchRemoteOperation.SearchType.FILE_SEARCH,
205+
false,
206+
OCCapability(23, 0, 0)
207+
).execute(
208+
client
209+
)
210+
211+
assertTrue(ror.isSuccess)
212+
assertEquals(2, ror.resultData.size)
213+
214+
val oldRemoteFile = ror.resultData[0]
215+
assertEquals(path, oldRemoteFile.remotePath)
216+
217+
ror = SearchRemoteOperation(
218+
"test",
219+
SearchRemoteOperation.SearchType.FILE_SEARCH,
220+
false,
221+
OCCapability(23, 0, 0)
222+
).execute(
223+
nextcloudClient
224+
)
225+
226+
assertTrue(ror.isSuccess)
227+
assertEquals(2, ror.resultData.size)
228+
229+
val remoteFile = ror.resultData[0]
230+
assertEquals(path, remoteFile.remotePath)
231+
232+
assertEquals(oldRemoteFile.remoteId, remoteFile.remoteId)
233+
}
234+
235+
@Test
236+
fun propPatch() {
237+
val path = "/testFolder/"
238+
239+
// create folder
240+
assertTrue(CreateFolderRemoteOperation(path, true).execute(client).isSuccess)
241+
242+
// make it favorite
243+
assertTrue(
244+
ToggleFavoriteRemoteOperation(true, path).execute(nextcloudClient).isSuccess
245+
)
246+
247+
val result = ReadFolderRemoteOperation(path).execute(client)
248+
assertTrue(result.isSuccess)
249+
val list = result.data as List<RemoteFile>
250+
assertTrue(list[0].isFavorite)
251+
}
252+
}

library/src/androidTest/java/com/owncloud/android/FileIT.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
*/
2727
package com.owncloud.android;
2828

29+
import static org.junit.Assert.assertEquals;
30+
import static org.junit.Assert.assertFalse;
31+
import static org.junit.Assert.assertTrue;
32+
2933
import android.net.Uri;
3034

3135
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
@@ -43,10 +47,6 @@
4347
import java.util.ArrayList;
4448
import java.util.List;
4549

46-
import static org.junit.Assert.assertEquals;
47-
import static org.junit.Assert.assertFalse;
48-
import static org.junit.Assert.assertTrue;
49-
5050
/**
5151
* Tests related to file operations
5252
*/
@@ -60,6 +60,7 @@ public void testCreateFolderSuccess() {
6060

6161
// verify folder
6262
assertTrue(new ReadFolderRemoteOperation(path).execute(client).isSuccess());
63+
assertTrue(new ReadFolderRemoteOperation(path).execute(nextcloudClient).isSuccess());
6364

6465
// remove folder
6566
assertTrue(new RemoveFileRemoteOperation(path).execute(client).isSuccess());

library/src/androidTest/java/com/owncloud/android/lib/resources/files/SearchRemoteOperationIT.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,22 +164,43 @@ public void noFavorites() {
164164
@Test
165165
public void oneFavorite() {
166166
String path = "/testFolder/";
167+
String path2 = "/testFolder2/";
167168

168169
// create folder, make it favorite
169170
new CreateFolderRemoteOperation(path, true).execute(client);
171+
new CreateFolderRemoteOperation(path2, true).execute(client);
170172
assertTrue(new ToggleFavoriteRemoteOperation(true, path).execute(client).isSuccess());
173+
assertTrue(new ToggleFavoriteRemoteOperation(true, path2).execute(nextcloudClient).isSuccess());
171174

172175
SearchRemoteOperation sut = new SearchRemoteOperation("",
173176
SearchRemoteOperation.SearchType.FAVORITE_SEARCH,
174177
false,
175178
capability);
176-
RemoteOperationResult<List<RemoteFile>> result = sut.execute(client);
179+
RemoteOperationResult<List<RemoteFile>> result = sut.execute(nextcloudClient);
177180

178181
// test
179182
assertTrue(result.isSuccess());
180-
assertEquals(1, result.getResultData().size());
183+
assertEquals(2, result.getResultData().size());
184+
181185
RemoteFile remoteFile = result.getResultData().get(0);
182186
assertEquals(path, remoteFile.getRemotePath());
187+
188+
RemoteFile remoteFile2 = result.getResultData().get(1);
189+
assertEquals(path2, remoteFile2.getRemotePath());
190+
191+
// unfavorite
192+
assertTrue(new ToggleFavoriteRemoteOperation(false, path).execute(client).isSuccess());
193+
assertTrue(new ToggleFavoriteRemoteOperation(false, path2).execute(nextcloudClient).isSuccess());
194+
195+
// test
196+
sut = new SearchRemoteOperation("",
197+
SearchRemoteOperation.SearchType.FAVORITE_SEARCH,
198+
false,
199+
capability);
200+
result = sut.execute(nextcloudClient);
201+
202+
assertTrue(result.isSuccess());
203+
assertEquals(0, result.getResultData().size());
183204
}
184205

185206
@Test

0 commit comments

Comments
 (0)