From 76a51600fde1f9b37628da143588add645d2f72f Mon Sep 17 00:00:00 2001 From: Nicolas Gelot Date: Fri, 28 Apr 2023 11:21:46 +0200 Subject: [PATCH 1/2] Fix modified timestamp for chunk upload For chunk upload we sent the timestamp from SyncedFileState which is defined in milli second while NextCloud excepts an Unix Timestamp in second. This patch provides the modified file date like it is done in `uploadFile` operation to be consistent. Ref: https://gitlab.e.foundation/e/backlog/-/issues/6784 --- .../foundation/e/drive/operations/UploadFileOperation.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java b/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java index 47645653..61ed2406 100644 --- a/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java +++ b/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java @@ -252,11 +252,12 @@ public class UploadFileOperation extends RemoteOperation { @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) @NonNull public RemoteOperationResult uploadChunkedFile(@NonNull final File file, @NonNull final OwnCloudClient client) { + final String timeStamp = ((Long) (file.lastModified() / 1000) ).toString() ; final String mimeType = CommonUtils.getMimeType(file); final ChunkedFileUploadRemoteOperation uploadOperation = new ChunkedFileUploadRemoteOperation(syncedState.getLocalPath(), syncedState.getRemotePath(), mimeType, syncedState.getLastETAG(), - syncedState.getLocalLastModified()+"", false); + timeStamp, false); return uploadOperation.execute(client); } -- GitLab From 28fb9931536d0faccf6d0b1ba118948d675ebe07 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Tue, 2 May 2023 11:09:14 +0200 Subject: [PATCH 2/2] refactor timestamp conversion from ms to second and add unit test for it --- .../drive/operations/UploadFileOperation.java | 14 ++++++++-- .../operations/UploadFileOperationTest.java | 26 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java b/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java index 61ed2406..75e09b3f 100644 --- a/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java +++ b/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java @@ -252,7 +252,7 @@ public class UploadFileOperation extends RemoteOperation { @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) @NonNull public RemoteOperationResult uploadChunkedFile(@NonNull final File file, @NonNull final OwnCloudClient client) { - final String timeStamp = ((Long) (file.lastModified() / 1000) ).toString() ; + final String timeStamp = formatTimestampToMatchCloud(file.lastModified()); final String mimeType = CommonUtils.getMimeType(file); final ChunkedFileUploadRemoteOperation uploadOperation = new ChunkedFileUploadRemoteOperation(syncedState.getLocalPath(), syncedState.getRemotePath(), @@ -306,7 +306,7 @@ public class UploadFileOperation extends RemoteOperation { @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) @NonNull public RemoteOperationResult uploadFile(@NonNull final File file, @NonNull final OwnCloudClient client, boolean checkEtag) { - final String timeStamp = ((Long) (file.lastModified() / 1000) ).toString(); + final String timeStamp = formatTimestampToMatchCloud(file.lastModified()); final String eTag = checkEtag ? syncedState.getLastETAG() : null; final UploadFileRemoteOperation uploadOperation = new UploadFileRemoteOperation(syncedState.getLocalPath(), @@ -335,4 +335,14 @@ public class UploadFileOperation extends RemoteOperation { public SyncedFileState getSyncedState() { return syncedState; } + + /** + * Convert local file timestamp to the format expected by the cloud + * On Android, file timestamp is a ms value, while nextcloud expect value in second + * @return String timestamp in second + */ + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + public @NonNull String formatTimestampToMatchCloud(long timestamp) { + return String.valueOf(timestamp/1000); + } } \ No newline at end of file diff --git a/app/src/test/java/foundation/e/drive/operations/UploadFileOperationTest.java b/app/src/test/java/foundation/e/drive/operations/UploadFileOperationTest.java index 2e2eaf48..28d9f1d3 100644 --- a/app/src/test/java/foundation/e/drive/operations/UploadFileOperationTest.java +++ b/app/src/test/java/foundation/e/drive/operations/UploadFileOperationTest.java @@ -314,6 +314,32 @@ public class UploadFileOperationTest { assertTrue("Expected result for ifMatchETagRequired(client) is true but got: false", addIfMatchHeader); } + @Test + public void formatTimeStampToMatchCloud_validTimestamp() { + final long initialTimestamp = 1683017095074L; + final String expectedOutput = "1683017095"; + final SyncedFileState mockedSyncedState = Mockito.mock(SyncedFileState.class); + final UploadFileOperation operationUnderTest = new UploadFileOperation(mockedSyncedState, account, context); + + final String output = operationUnderTest.formatTimestampToMatchCloud(initialTimestamp); + assertNotNull("Output shouldn't be null", output); + assertFalse("Output shouldn't not be empty.", output.isEmpty()); + assertEquals("Output doesn't match expectation.", expectedOutput, output); + } + + @Test + public void formatTimeStampToMatchCloud_invalidTimestamp() { + final long initialTimestamp = 0; + final String expectedOutput = "0"; + final SyncedFileState mockedSyncedState = Mockito.mock(SyncedFileState.class); + final UploadFileOperation operationUnderTest = new UploadFileOperation(mockedSyncedState, account, context); + + final String output = operationUnderTest.formatTimestampToMatchCloud(initialTimestamp); + assertNotNull("Output shouldn't be null", output); + assertFalse("Output shouldn't not be empty.", output.isEmpty()); + assertEquals("Output doesn't match expectation.", expectedOutput, output); + } + private void mockUserInfoReading(UploadFileOperation instanceUnderTest) { final long userTotalQuota = 100; final long userUsedQuota = 50; -- GitLab