FileUploaderIT.kt 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  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.storagePath = 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. storageManager
  180. )
  181. .setRemoteFolderToBeCreated()
  182. .execute(client)
  183. .isSuccess
  184. )
  185. val result = ReadFileRemoteOperation("/testFile.txt").execute(client)
  186. assertTrue(result.isSuccess)
  187. assertEquals(file.length(), (result.data[0] as RemoteFile).length)
  188. val file2 = getDummyFile("empty.txt")
  189. val ocUpload2 = OCUpload(file2.absolutePath, "/testFile.txt", account.name)
  190. assertTrue(
  191. UploadFileOperation(
  192. uploadsStorageManager,
  193. connectivityServiceMock,
  194. powerManagementServiceMock,
  195. user,
  196. null,
  197. ocUpload2,
  198. NameCollisionPolicy.RENAME,
  199. FileUploader.LOCAL_BEHAVIOUR_COPY,
  200. targetContext,
  201. false,
  202. false,
  203. storageManager
  204. )
  205. .addRenameUploadListener {
  206. renameListenerWasTriggered = true
  207. }
  208. .execute(client)
  209. .isSuccess
  210. )
  211. val result2 = ReadFileRemoteOperation("/testFile.txt").execute(client)
  212. assertTrue(result2.isSuccess)
  213. assertEquals(file.length(), (result2.data[0] as RemoteFile).length)
  214. val result3 = ReadFileRemoteOperation("/testFile (2).txt").execute(client)
  215. assertTrue(result3.isSuccess)
  216. assertEquals(file2.length(), (result3.data[0] as RemoteFile).length)
  217. assertTrue(renameListenerWasTriggered)
  218. }
  219. /**
  220. * uploads a file, uploads another one with automatically (2) added, check
  221. */
  222. @Test
  223. fun testKeepBothStatic() {
  224. val file = getDummyFile("/chunkedFile.txt")
  225. FileUploader.uploadNewFile(
  226. targetContext,
  227. account,
  228. file.absolutePath,
  229. "/testFile.txt",
  230. FileUploader.LOCAL_BEHAVIOUR_COPY,
  231. null,
  232. true,
  233. UploadFileOperation.CREATED_BY_USER,
  234. false,
  235. false,
  236. NameCollisionPolicy.DEFAULT
  237. )
  238. longSleep()
  239. val result = ReadFileRemoteOperation("/testFile.txt").execute(client)
  240. assertTrue(result.isSuccess)
  241. assertEquals(file.length(), (result.data[0] as RemoteFile).length)
  242. val ocFile2 = OCFile("/testFile.txt")
  243. ocFile2.storagePath = getDummyFile("/empty.txt").absolutePath
  244. FileUploader.uploadUpdateFile(
  245. targetContext,
  246. account,
  247. ocFile2,
  248. FileUploader.LOCAL_BEHAVIOUR_COPY,
  249. NameCollisionPolicy.RENAME
  250. )
  251. shortSleep()
  252. val result2 = ReadFileRemoteOperation("/testFile.txt").execute(client)
  253. assertTrue(result2.isSuccess)
  254. assertEquals(file.length(), (result2.data[0] as RemoteFile).length)
  255. val result3 = ReadFileRemoteOperation("/testFile (2).txt").execute(client)
  256. assertTrue(result3.isSuccess)
  257. assertEquals(ocFile2.fileLength, (result3.data[0] as RemoteFile).length)
  258. }
  259. /**
  260. * uploads a file with "keep server" option set, so do nothing
  261. */
  262. @Test
  263. fun testKeepServer() {
  264. val file = getDummyFile("/chunkedFile.txt")
  265. val ocUpload = OCUpload(file.absolutePath, "/testFile.txt", account.name)
  266. assertTrue(
  267. UploadFileOperation(
  268. uploadsStorageManager,
  269. connectivityServiceMock,
  270. powerManagementServiceMock,
  271. user,
  272. null,
  273. ocUpload,
  274. NameCollisionPolicy.DEFAULT,
  275. FileUploader.LOCAL_BEHAVIOUR_COPY,
  276. targetContext,
  277. false,
  278. false,
  279. storageManager
  280. )
  281. .setRemoteFolderToBeCreated()
  282. .execute(client)
  283. .isSuccess
  284. )
  285. val result = ReadFileRemoteOperation("/testFile.txt").execute(client)
  286. assertTrue(result.isSuccess)
  287. assertEquals(file.length(), (result.data[0] as RemoteFile).length)
  288. val ocUpload2 = OCUpload(getDummyFile("/empty.txt").absolutePath, "/testFile.txt", account.name)
  289. assertFalse(
  290. UploadFileOperation(
  291. uploadsStorageManager,
  292. connectivityServiceMock,
  293. powerManagementServiceMock,
  294. user,
  295. null,
  296. ocUpload2,
  297. NameCollisionPolicy.CANCEL,
  298. FileUploader.LOCAL_BEHAVIOUR_COPY,
  299. targetContext,
  300. false,
  301. false,
  302. storageManager
  303. )
  304. .execute(client).isSuccess
  305. )
  306. val result2 = ReadFileRemoteOperation("/testFile.txt").execute(client)
  307. assertTrue(result2.isSuccess)
  308. assertEquals(file.length(), (result2.data[0] as RemoteFile).length)
  309. }
  310. /**
  311. * uploads a file with "keep server" option set, so do nothing
  312. */
  313. @Test
  314. fun testKeepServerStatic() {
  315. val file = getDummyFile("/chunkedFile.txt")
  316. FileUploader.uploadNewFile(
  317. targetContext,
  318. account,
  319. file.absolutePath,
  320. "/testFile.txt",
  321. FileUploader.LOCAL_BEHAVIOUR_COPY,
  322. null,
  323. true,
  324. UploadFileOperation.CREATED_BY_USER,
  325. false,
  326. false,
  327. NameCollisionPolicy.DEFAULT
  328. )
  329. longSleep()
  330. val result = ReadFileRemoteOperation("/testFile.txt").execute(client)
  331. assertTrue(result.isSuccess)
  332. assertEquals(file.length(), (result.data[0] as RemoteFile).length)
  333. val ocFile2 = OCFile("/testFile.txt")
  334. ocFile2.storagePath = getDummyFile("/empty.txt").absolutePath
  335. FileUploader.uploadUpdateFile(
  336. targetContext,
  337. account,
  338. ocFile2,
  339. FileUploader.LOCAL_BEHAVIOUR_COPY,
  340. NameCollisionPolicy.CANCEL
  341. )
  342. shortSleep()
  343. val result2 = ReadFileRemoteOperation("/testFile.txt").execute(client)
  344. assertTrue(result2.isSuccess)
  345. assertEquals(file.length(), (result2.data[0] as RemoteFile).length)
  346. }
  347. /**
  348. * uploads a file with "skip if exists" option set, so do nothing if file exists
  349. */
  350. @Test
  351. fun testCancelServer() {
  352. val file = getDummyFile("/chunkedFile.txt")
  353. val ocUpload = OCUpload(file.absolutePath, "/testFile.txt", account.name)
  354. assertTrue(
  355. UploadFileOperation(
  356. uploadsStorageManager,
  357. connectivityServiceMock,
  358. powerManagementServiceMock,
  359. user,
  360. null,
  361. ocUpload,
  362. NameCollisionPolicy.CANCEL,
  363. FileUploader.LOCAL_BEHAVIOUR_COPY,
  364. targetContext,
  365. false,
  366. false,
  367. storageManager
  368. )
  369. .setRemoteFolderToBeCreated()
  370. .execute(client)
  371. .isSuccess
  372. )
  373. val result = ReadFileRemoteOperation("/testFile.txt").execute(client)
  374. assertTrue(result.isSuccess)
  375. assertEquals(file.length(), (result.data[0] as RemoteFile).length)
  376. val ocUpload2 = OCUpload(getDummyFile("/empty.txt").absolutePath, "/testFile.txt", account.name)
  377. val uploadResult = UploadFileOperation(
  378. uploadsStorageManager,
  379. connectivityServiceMock,
  380. powerManagementServiceMock,
  381. user,
  382. null,
  383. ocUpload2,
  384. NameCollisionPolicy.CANCEL,
  385. FileUploader.LOCAL_BEHAVIOUR_COPY,
  386. targetContext,
  387. false,
  388. false,
  389. storageManager
  390. )
  391. .execute(client)
  392. assertFalse(uploadResult.isSuccess)
  393. assertTrue(uploadResult.exception is OperationCancelledException)
  394. val result2 = ReadFileRemoteOperation("/testFile.txt").execute(client)
  395. assertTrue(result2.isSuccess)
  396. assertEquals(file.length(), (result2.data[0] as RemoteFile).length)
  397. }
  398. /**
  399. * uploads a file with "skip if exists" option set, so do nothing if file exists
  400. */
  401. @Test
  402. fun testKeepCancelStatic() {
  403. val file = getDummyFile("/chunkedFile.txt")
  404. FileUploader.uploadNewFile(
  405. targetContext,
  406. account,
  407. file.absolutePath,
  408. "/testFile.txt",
  409. FileUploader.LOCAL_BEHAVIOUR_COPY,
  410. null,
  411. true,
  412. UploadFileOperation.CREATED_BY_USER,
  413. false,
  414. false,
  415. NameCollisionPolicy.DEFAULT
  416. )
  417. longSleep()
  418. val result = ReadFileRemoteOperation("/testFile.txt").execute(client)
  419. assertTrue(result.isSuccess)
  420. assertEquals(file.length(), (result.data[0] as RemoteFile).length)
  421. val ocFile2 = OCFile("/testFile.txt")
  422. ocFile2.storagePath = getDummyFile("/empty.txt").absolutePath
  423. FileUploader.uploadUpdateFile(
  424. targetContext,
  425. account,
  426. ocFile2,
  427. FileUploader.LOCAL_BEHAVIOUR_COPY,
  428. NameCollisionPolicy.CANCEL
  429. )
  430. shortSleep()
  431. val result2 = ReadFileRemoteOperation("/testFile.txt").execute(client)
  432. assertTrue(result2.isSuccess)
  433. assertEquals(file.length(), (result2.data[0] as RemoteFile).length)
  434. }
  435. }