FileUploaderIT.kt 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. /*
  2. *
  3. * Nextcloud Android client application
  4. *
  5. * @author Tobias Kaminsky
  6. * Copyright (C) 2020 Tobias Kaminsky
  7. * Copyright (C) 2020 Nextcloud GmbH
  8. * Copyright (C) 2020 Chris Narkiewicz <hello@ezaquarii.com>
  9. *
  10. * This program is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Affero General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU Affero General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Affero General Public License
  21. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  22. */
  23. package com.owncloud.android.files.services
  24. import com.nextcloud.client.account.UserAccountManager
  25. import com.nextcloud.client.account.UserAccountManagerImpl
  26. import com.nextcloud.client.device.BatteryStatus
  27. import com.nextcloud.client.device.PowerManagementService
  28. import com.nextcloud.client.network.Connectivity
  29. import com.nextcloud.client.network.ConnectivityService
  30. import com.owncloud.android.AbstractOnServerIT
  31. import com.owncloud.android.datamodel.OCFile
  32. import com.owncloud.android.datamodel.UploadsStorageManager
  33. import com.owncloud.android.db.OCUpload
  34. import com.owncloud.android.lib.common.operations.OperationCancelledException
  35. import com.owncloud.android.lib.resources.files.ReadFileRemoteOperation
  36. import com.owncloud.android.lib.resources.files.model.RemoteFile
  37. import com.owncloud.android.operations.UploadFileOperation
  38. import junit.framework.Assert.assertEquals
  39. import junit.framework.Assert.assertFalse
  40. import junit.framework.Assert.assertTrue
  41. import org.junit.Before
  42. import org.junit.Test
  43. class FileUploaderIT : AbstractOnServerIT() {
  44. var uploadsStorageManager: UploadsStorageManager? = null
  45. val connectivityServiceMock: ConnectivityService = object : ConnectivityService {
  46. override fun isInternetWalled(): Boolean = false
  47. override fun getConnectivity(): Connectivity = Connectivity.CONNECTED_WIFI
  48. }
  49. private val powerManagementServiceMock: PowerManagementService = object : PowerManagementService {
  50. override val isPowerSavingEnabled: Boolean
  51. get() = false
  52. override val isPowerSavingExclusionAvailable: Boolean
  53. get() = false
  54. override val battery: BatteryStatus
  55. get() = BatteryStatus()
  56. }
  57. @Before
  58. fun setUp() {
  59. val contentResolver = targetContext.contentResolver
  60. val accountManager: UserAccountManager = UserAccountManagerImpl.fromContext(targetContext)
  61. uploadsStorageManager = UploadsStorageManager(accountManager, contentResolver)
  62. }
  63. /**
  64. * uploads a file, overwrites it with an empty one, check if overwritten
  65. */
  66. // disabled, flaky test
  67. // @Test
  68. // fun testKeepLocalAndOverwriteRemote() {
  69. // val file = getDummyFile("/chunkedFile.txt")
  70. // val ocUpload = OCUpload(file.absolutePath, "/testFile.txt", account.name)
  71. //
  72. // assertTrue(
  73. // UploadFileOperation(
  74. // uploadsStorageManager,
  75. // connectivityServiceMock,
  76. // powerManagementServiceMock,
  77. // user,
  78. // null,
  79. // ocUpload,
  80. // FileUploader.NameCollisionPolicy.DEFAULT,
  81. // FileUploader.LOCAL_BEHAVIOUR_COPY,
  82. // targetContext,
  83. // false,
  84. // false
  85. // )
  86. // .setRemoteFolderToBeCreated()
  87. // .execute(client, storageManager)
  88. // .isSuccess
  89. // )
  90. //
  91. // val result = ReadFileRemoteOperation("/testFile.txt").execute(client)
  92. // assertTrue(result.isSuccess)
  93. //
  94. // assertEquals(file.length(), (result.data[0] as RemoteFile).length)
  95. //
  96. // val ocUpload2 = OCUpload(getDummyFile("/empty.txt").absolutePath, "/testFile.txt", account.name)
  97. //
  98. // assertTrue(
  99. // UploadFileOperation(
  100. // uploadsStorageManager,
  101. // connectivityServiceMock,
  102. // powerManagementServiceMock,
  103. // user,
  104. // null,
  105. // ocUpload2,
  106. // FileUploader.NameCollisionPolicy.OVERWRITE,
  107. // FileUploader.LOCAL_BEHAVIOUR_COPY,
  108. // targetContext,
  109. // false,
  110. // false
  111. // )
  112. // .execute(client, storageManager)
  113. // .isSuccess
  114. // )
  115. //
  116. // val result2 = ReadFileRemoteOperation("/testFile.txt").execute(client)
  117. // assertTrue(result2.isSuccess)
  118. //
  119. // assertEquals(0, (result2.data[0] as RemoteFile).length)
  120. // }
  121. /**
  122. * uploads a file, overwrites it with an empty one, check if overwritten
  123. */
  124. @Test
  125. fun testKeepLocalAndOverwriteRemoteStatic() {
  126. val file = getDummyFile("/chunkedFile.txt")
  127. FileUploader.uploadNewFile(
  128. targetContext,
  129. account,
  130. file.absolutePath,
  131. "/testFile.txt",
  132. FileUploader.LOCAL_BEHAVIOUR_COPY,
  133. null,
  134. true,
  135. UploadFileOperation.CREATED_BY_USER,
  136. false,
  137. false,
  138. NameCollisionPolicy.DEFAULT
  139. )
  140. longSleep()
  141. val result = ReadFileRemoteOperation("/testFile.txt").execute(client)
  142. assertTrue(result.isSuccess)
  143. assertEquals(file.length(), (result.data[0] as RemoteFile).length)
  144. val ocFile2 = OCFile("/testFile.txt")
  145. ocFile2.setStoragePath(getDummyFile("/empty.txt").absolutePath)
  146. FileUploader.uploadUpdateFile(
  147. targetContext,
  148. account,
  149. ocFile2,
  150. FileUploader.LOCAL_BEHAVIOUR_COPY,
  151. NameCollisionPolicy.OVERWRITE
  152. )
  153. shortSleep()
  154. val result2 = ReadFileRemoteOperation("/testFile.txt").execute(client)
  155. assertTrue(result2.isSuccess)
  156. assertEquals(0, (result2.data[0] as RemoteFile).length)
  157. }
  158. /**
  159. * uploads a file, uploads another one with automatically (2) added, check
  160. */
  161. @Test
  162. fun testKeepBoth() {
  163. var renameListenerWasTriggered = false
  164. val file = getDummyFile("/chunkedFile.txt")
  165. val ocUpload = OCUpload(file.absolutePath, "/testFile.txt", account.name)
  166. assertTrue(
  167. UploadFileOperation(
  168. uploadsStorageManager,
  169. connectivityServiceMock,
  170. powerManagementServiceMock,
  171. user,
  172. null,
  173. ocUpload,
  174. NameCollisionPolicy.DEFAULT,
  175. FileUploader.LOCAL_BEHAVIOUR_COPY,
  176. targetContext,
  177. false,
  178. false
  179. )
  180. .setRemoteFolderToBeCreated()
  181. .execute(client, storageManager)
  182. .isSuccess
  183. )
  184. val result = ReadFileRemoteOperation("/testFile.txt").execute(client)
  185. assertTrue(result.isSuccess)
  186. assertEquals(file.length(), (result.data[0] as RemoteFile).length)
  187. val file2 = getDummyFile("empty.txt")
  188. val ocUpload2 = OCUpload(file2.absolutePath, "/testFile.txt", account.name)
  189. assertTrue(
  190. UploadFileOperation(
  191. uploadsStorageManager,
  192. connectivityServiceMock,
  193. powerManagementServiceMock,
  194. user,
  195. null,
  196. ocUpload2,
  197. NameCollisionPolicy.RENAME,
  198. FileUploader.LOCAL_BEHAVIOUR_COPY,
  199. targetContext,
  200. false,
  201. false
  202. )
  203. .addRenameUploadListener {
  204. renameListenerWasTriggered = true
  205. }
  206. .execute(client, storageManager)
  207. .isSuccess
  208. )
  209. val result2 = ReadFileRemoteOperation("/testFile.txt").execute(client)
  210. assertTrue(result2.isSuccess)
  211. assertEquals(file.length(), (result2.data[0] as RemoteFile).length)
  212. val result3 = ReadFileRemoteOperation("/testFile (2).txt").execute(client)
  213. assertTrue(result3.isSuccess)
  214. assertEquals(file2.length(), (result3.data[0] as RemoteFile).length)
  215. assertTrue(renameListenerWasTriggered)
  216. }
  217. /**
  218. * uploads a file, uploads another one with automatically (2) added, check
  219. */
  220. @Test
  221. fun testKeepBothStatic() {
  222. val file = getDummyFile("/chunkedFile.txt")
  223. FileUploader.uploadNewFile(
  224. targetContext,
  225. account,
  226. file.absolutePath,
  227. "/testFile.txt",
  228. FileUploader.LOCAL_BEHAVIOUR_COPY,
  229. null,
  230. true,
  231. UploadFileOperation.CREATED_BY_USER,
  232. false,
  233. false,
  234. NameCollisionPolicy.DEFAULT
  235. )
  236. longSleep()
  237. val result = ReadFileRemoteOperation("/testFile.txt").execute(client)
  238. assertTrue(result.isSuccess)
  239. assertEquals(file.length(), (result.data[0] as RemoteFile).length)
  240. val ocFile2 = OCFile("/testFile.txt")
  241. ocFile2.setStoragePath(getDummyFile("/empty.txt").absolutePath)
  242. FileUploader.uploadUpdateFile(
  243. targetContext,
  244. account,
  245. ocFile2,
  246. FileUploader.LOCAL_BEHAVIOUR_COPY,
  247. NameCollisionPolicy.RENAME
  248. )
  249. shortSleep()
  250. val result2 = ReadFileRemoteOperation("/testFile.txt").execute(client)
  251. assertTrue(result2.isSuccess)
  252. assertEquals(file.length(), (result2.data[0] as RemoteFile).length)
  253. val result3 = ReadFileRemoteOperation("/testFile (2).txt").execute(client)
  254. assertTrue(result3.isSuccess)
  255. assertEquals(ocFile2.fileLength, (result3.data[0] as RemoteFile).length)
  256. }
  257. /**
  258. * uploads a file with "keep server" option set, so do nothing
  259. */
  260. @Test
  261. fun testKeepServer() {
  262. val file = getDummyFile("/chunkedFile.txt")
  263. val ocUpload = OCUpload(file.absolutePath, "/testFile.txt", account.name)
  264. assertTrue(
  265. UploadFileOperation(
  266. uploadsStorageManager,
  267. connectivityServiceMock,
  268. powerManagementServiceMock,
  269. user,
  270. null,
  271. ocUpload,
  272. NameCollisionPolicy.DEFAULT,
  273. FileUploader.LOCAL_BEHAVIOUR_COPY,
  274. targetContext,
  275. false,
  276. false
  277. )
  278. .setRemoteFolderToBeCreated()
  279. .execute(client, storageManager)
  280. .isSuccess
  281. )
  282. val result = ReadFileRemoteOperation("/testFile.txt").execute(client)
  283. assertTrue(result.isSuccess)
  284. assertEquals(file.length(), (result.data[0] as RemoteFile).length)
  285. val ocUpload2 = OCUpload(getDummyFile("/empty.txt").absolutePath, "/testFile.txt", account.name)
  286. assertFalse(
  287. UploadFileOperation(
  288. uploadsStorageManager,
  289. connectivityServiceMock,
  290. powerManagementServiceMock,
  291. user,
  292. null,
  293. ocUpload2,
  294. NameCollisionPolicy.CANCEL,
  295. FileUploader.LOCAL_BEHAVIOUR_COPY,
  296. targetContext,
  297. false,
  298. false
  299. )
  300. .execute(client, storageManager).isSuccess
  301. )
  302. val result2 = ReadFileRemoteOperation("/testFile.txt").execute(client)
  303. assertTrue(result2.isSuccess)
  304. assertEquals(file.length(), (result2.data[0] as RemoteFile).length)
  305. }
  306. /**
  307. * uploads a file with "keep server" option set, so do nothing
  308. */
  309. @Test
  310. fun testKeepServerStatic() {
  311. val file = getDummyFile("/chunkedFile.txt")
  312. FileUploader.uploadNewFile(
  313. targetContext,
  314. account,
  315. file.absolutePath,
  316. "/testFile.txt",
  317. FileUploader.LOCAL_BEHAVIOUR_COPY,
  318. null,
  319. true,
  320. UploadFileOperation.CREATED_BY_USER,
  321. false,
  322. false,
  323. NameCollisionPolicy.DEFAULT
  324. )
  325. longSleep()
  326. val result = ReadFileRemoteOperation("/testFile.txt").execute(client)
  327. assertTrue(result.isSuccess)
  328. assertEquals(file.length(), (result.data[0] as RemoteFile).length)
  329. val ocFile2 = OCFile("/testFile.txt")
  330. ocFile2.setStoragePath(getDummyFile("/empty.txt").absolutePath)
  331. FileUploader.uploadUpdateFile(
  332. targetContext,
  333. account,
  334. ocFile2,
  335. FileUploader.LOCAL_BEHAVIOUR_COPY,
  336. NameCollisionPolicy.CANCEL
  337. )
  338. shortSleep()
  339. val result2 = ReadFileRemoteOperation("/testFile.txt").execute(client)
  340. assertTrue(result2.isSuccess)
  341. assertEquals(file.length(), (result2.data[0] as RemoteFile).length)
  342. }
  343. /**
  344. * uploads a file with "skip if exists" option set, so do nothing if file exists
  345. */
  346. @Test
  347. fun testCancelServer() {
  348. val file = getDummyFile("/chunkedFile.txt")
  349. val ocUpload = OCUpload(file.absolutePath, "/testFile.txt", account.name)
  350. assertTrue(
  351. UploadFileOperation(
  352. uploadsStorageManager,
  353. connectivityServiceMock,
  354. powerManagementServiceMock,
  355. user,
  356. null,
  357. ocUpload,
  358. NameCollisionPolicy.CANCEL,
  359. FileUploader.LOCAL_BEHAVIOUR_COPY,
  360. targetContext,
  361. false,
  362. false
  363. )
  364. .setRemoteFolderToBeCreated()
  365. .execute(client, storageManager)
  366. .isSuccess
  367. )
  368. val result = ReadFileRemoteOperation("/testFile.txt").execute(client)
  369. assertTrue(result.isSuccess)
  370. assertEquals(file.length(), (result.data[0] as RemoteFile).length)
  371. val ocUpload2 = OCUpload(getDummyFile("/empty.txt").absolutePath, "/testFile.txt", account.name)
  372. val uploadResult = UploadFileOperation(
  373. uploadsStorageManager,
  374. connectivityServiceMock,
  375. powerManagementServiceMock,
  376. user,
  377. null,
  378. ocUpload2,
  379. NameCollisionPolicy.CANCEL,
  380. FileUploader.LOCAL_BEHAVIOUR_COPY,
  381. targetContext,
  382. false,
  383. false
  384. )
  385. .execute(client, storageManager)
  386. assertFalse(uploadResult.isSuccess)
  387. assertTrue(uploadResult.exception is OperationCancelledException)
  388. val result2 = ReadFileRemoteOperation("/testFile.txt").execute(client)
  389. assertTrue(result2.isSuccess)
  390. assertEquals(file.length(), (result2.data[0] as RemoteFile).length)
  391. }
  392. /**
  393. * uploads a file with "skip if exists" option set, so do nothing if file exists
  394. */
  395. @Test
  396. fun testKeepCancelStatic() {
  397. val file = getDummyFile("/chunkedFile.txt")
  398. FileUploader.uploadNewFile(
  399. targetContext,
  400. account,
  401. file.absolutePath,
  402. "/testFile.txt",
  403. FileUploader.LOCAL_BEHAVIOUR_COPY,
  404. null,
  405. true,
  406. UploadFileOperation.CREATED_BY_USER,
  407. false,
  408. false,
  409. NameCollisionPolicy.DEFAULT
  410. )
  411. longSleep()
  412. val result = ReadFileRemoteOperation("/testFile.txt").execute(client)
  413. assertTrue(result.isSuccess)
  414. assertEquals(file.length(), (result.data[0] as RemoteFile).length)
  415. val ocFile2 = OCFile("/testFile.txt")
  416. ocFile2.setStoragePath(getDummyFile("/empty.txt").absolutePath)
  417. FileUploader.uploadUpdateFile(
  418. targetContext,
  419. account,
  420. ocFile2,
  421. FileUploader.LOCAL_BEHAVIOUR_COPY,
  422. NameCollisionPolicy.CANCEL
  423. )
  424. shortSleep()
  425. val result2 = ReadFileRemoteOperation("/testFile.txt").execute(client)
  426. assertTrue(result2.isSuccess)
  427. assertEquals(file.length(), (result2.data[0] as RemoteFile).length)
  428. }
  429. }