From 326101edf39c13bed942855f59ebf0014ca5fd8b Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Tue, 27 Jan 2026 10:37:46 +0100 Subject: [PATCH 1/3] test: add unit tests for DisplayUtils and UploadEntity conversions Signed-off-by: alperozturk96 --- .../nextcloud/client/utils/UploadDateTests.kt | 256 ++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 app/src/test/java/com/nextcloud/client/utils/UploadDateTests.kt diff --git a/app/src/test/java/com/nextcloud/client/utils/UploadDateTests.kt b/app/src/test/java/com/nextcloud/client/utils/UploadDateTests.kt new file mode 100644 index 000000000000..bd32d4ed0295 --- /dev/null +++ b/app/src/test/java/com/nextcloud/client/utils/UploadDateTests.kt @@ -0,0 +1,256 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2026 Alper Ozturk + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.nextcloud.client.utils + +import android.content.Context +import android.text.format.DateUtils +import com.nextcloud.client.database.entity.UploadEntity +import com.nextcloud.client.database.entity.toOCUpload +import com.nextcloud.client.database.entity.toUploadEntity +import com.owncloud.android.utils.DisplayUtils +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Test +import com.owncloud.android.R +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkStatic +import org.junit.Before +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + +class UploadConversionTest { + + companion object { + private const val JANUARY_27_2026 = 1769505718000 + private const val ONE_YEAR = 365L * 24 * 60 * 60 * 1000 + private const val ONE_MONTH = 30L * 24 * 60 * 60 * 1000 + private const val ONE_WEEK = 7 * 24 * 60 * 60 * 1000 + private const val TWO_HOURS = 2 * 60 * 60 * 1000 + private const val ONE_MINUTE = 60_000 + private const val THIRTY_SECONDS = 30_000 + + private const val DATE_FORMATTER_PATTERN = "MMM dd, yyyy, hh:mm:ss a" + } + + private lateinit var context: Context + + @Before + fun setup() { + context = mockk(relaxed = true) + mockkStatic(DateUtils::class) + } + + @Test + fun `UploadEntity converts to OCUpload and back correctly`() { + val entity = UploadEntity( + id = 123, + localPath = "/local/file.txt", + remotePath = "/remote/file.txt", + accountName = "test@example.com", + fileSize = 1024L, + status = 2, + localBehaviour = 1, + uploadTime = null, + nameCollisionPolicy = 0, + isCreateRemoteFolder = 1, + uploadEndTimestamp = 0, + uploadEndTimestampLong = 1_650_000_000_000, + lastResult = 0, + isWhileChargingOnly = 1, + isWifiOnly = 1, + createdBy = 5, + folderUnlockToken = "token123" + ) + + val upload = entity.toOCUpload() + assertNotNull(upload) + assertEquals(entity.localPath, upload?.localPath) + assertEquals(entity.remotePath, upload?.remotePath) + assertEquals(entity.uploadEndTimestampLong, upload?.uploadEndTimestamp) + + val convertedEntity = upload!!.toUploadEntity() + assertEquals(entity.localPath, convertedEntity.localPath) + assertEquals(entity.remotePath, convertedEntity.remotePath) + assertEquals(entity.uploadEndTimestampLong, convertedEntity.uploadEndTimestampLong) + assertEquals(entity.isCreateRemoteFolder, convertedEntity.isCreateRemoteFolder) + assertEquals(entity.isWifiOnly, convertedEntity.isWifiOnly) + assertEquals(entity.isWhileChargingOnly, convertedEntity.isWhileChargingOnly) + } + + @Test + fun `getRelativeDateTimeString returns seconds ago for recent past`() { + val expectedResult = "seconds ago" + + every { context.getString(R.string.file_list_seconds_ago) } returns "seconds ago" + + every { + DateUtils.getRelativeDateTimeString( + any(), + any(), + any(), + any(), + any() + ) + } answers { expectedResult } + + val time = JANUARY_27_2026 - THIRTY_SECONDS + + val result = DisplayUtils.getRelativeDateTimeString( + context, + time, + DateUtils.SECOND_IN_MILLIS, + DateUtils.WEEK_IN_MILLIS, + 0 + ) + + assertEquals(expectedResult, result) + } + + @Test + fun `getRelativeDateTimeString returns future as human readable when showFuture is false`() { + val formatter = SimpleDateFormat(DATE_FORMATTER_PATTERN, Locale.US) + + val time = JANUARY_27_2026 + ONE_MINUTE + val timeAsDate = Date(time) + val expectedString = formatter.format(timeAsDate) + + every { + DateUtils.getRelativeDateTimeString( + any(), + any(), + any(), + any(), + any() + ) + } answers { expectedString } + + val result = DisplayUtils.getRelativeDateTimeString( + context, + time, + DateUtils.SECOND_IN_MILLIS, + DateUtils.WEEK_IN_MILLIS, + 0 + ) + + val normalizedResult = result.toString().normalizeResult() + val normalizedExpected = expectedString.normalizeResult() + assertEquals(normalizedExpected, normalizedResult) + } + + @Test + fun `getRelativeDateTimeString returns proper relative string for hours ago`() { + every { + DateUtils.getRelativeDateTimeString( + any(), + any(), + any(), + any(), + any() + ) + } answers { "2 hours ago" } + + val time = JANUARY_27_2026 - TWO_HOURS + + val result = DisplayUtils.getRelativeDateTimeString( + context, + time, + DateUtils.MINUTE_IN_MILLIS, + DateUtils.WEEK_IN_MILLIS, + 0 + ) + + assert(result.isNotEmpty()) + } + + @Test + fun `getRelativeDateTimeString returns relative string for one week ago`() { + val expectedResult = "Jan 20" + + every { + DateUtils.getRelativeDateTimeString( + any(), + any(), + any(), + any(), + any() + ) + } answers { expectedResult } + + val time = JANUARY_27_2026 - ONE_WEEK + + val result = DisplayUtils.getRelativeDateTimeString( + context, + time, + DateUtils.MINUTE_IN_MILLIS, + DateUtils.WEEK_IN_MILLIS, + 0 + ) + + assertEquals(expectedResult, result) + } + + @Test + fun `getRelativeDateTimeString returns relative string for one month ago`() { + val expectedResult = "12/28/2025" + + every { + DateUtils.getRelativeDateTimeString( + any(), + any(), + any(), + any(), + any() + ) + } answers { expectedResult } + + val time = JANUARY_27_2026 - ONE_MONTH + + val result = DisplayUtils.getRelativeDateTimeString( + context, + time, + DateUtils.DAY_IN_MILLIS, + DateUtils.WEEK_IN_MILLIS, + 0 + ) + + assertEquals(expectedResult, result) + } + + @Test + fun `getRelativeDateTimeString returns relative string for one year ago`() { + val expectedResult = "1/27/2025" + + every { + DateUtils.getRelativeDateTimeString( + any(), + any(), + any(), + any(), + any() + ) + } answers { expectedResult } + + val time = JANUARY_27_2026 - ONE_YEAR + + val result = DisplayUtils.getRelativeDateTimeString( + context, + time, + DateUtils.DAY_IN_MILLIS, + DateUtils.WEEK_IN_MILLIS, + 0 + ) + + assertEquals(expectedResult, result) + } + + private fun String.normalizeResult(): String { + return replace('\u202F', ' ').replace('\u00A0', ' ') + } +} From b4c366fc77449a862f7d1b0632068f641cd979c1 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Tue, 27 Jan 2026 10:40:22 +0100 Subject: [PATCH 2/3] test: add unit tests for DisplayUtils and UploadEntity conversions Signed-off-by: alperozturk96 --- .../nextcloud/client/utils/UploadDateTests.kt | 153 ++++-------------- 1 file changed, 27 insertions(+), 126 deletions(-) diff --git a/app/src/test/java/com/nextcloud/client/utils/UploadDateTests.kt b/app/src/test/java/com/nextcloud/client/utils/UploadDateTests.kt index bd32d4ed0295..fa27cc6e167f 100644 --- a/app/src/test/java/com/nextcloud/client/utils/UploadDateTests.kt +++ b/app/src/test/java/com/nextcloud/client/utils/UploadDateTests.kt @@ -25,7 +25,7 @@ import java.text.SimpleDateFormat import java.util.Date import java.util.Locale -class UploadConversionTest { +class UploadDateTests { companion object { private const val JANUARY_27_2026 = 1769505718000 @@ -86,147 +86,59 @@ class UploadConversionTest { @Test fun `getRelativeDateTimeString returns seconds ago for recent past`() { - val expectedResult = "seconds ago" + val expected = "seconds ago" + every { context.getString(R.string.file_list_seconds_ago) } returns expected - every { context.getString(R.string.file_list_seconds_ago) } returns "seconds ago" - - every { - DateUtils.getRelativeDateTimeString( - any(), - any(), - any(), - any(), - any() - ) - } answers { expectedResult } - - val time = JANUARY_27_2026 - THIRTY_SECONDS - - val result = DisplayUtils.getRelativeDateTimeString( - context, - time, - DateUtils.SECOND_IN_MILLIS, - DateUtils.WEEK_IN_MILLIS, - 0 - ) - - assertEquals(expectedResult, result) + assertRelativeDateTimeString(JANUARY_27_2026 - THIRTY_SECONDS, expected, DateUtils.SECOND_IN_MILLIS) } @Test fun `getRelativeDateTimeString returns future as human readable when showFuture is false`() { val formatter = SimpleDateFormat(DATE_FORMATTER_PATTERN, Locale.US) - val time = JANUARY_27_2026 + ONE_MINUTE - val timeAsDate = Date(time) - val expectedString = formatter.format(timeAsDate) - - every { - DateUtils.getRelativeDateTimeString( - any(), - any(), - any(), - any(), - any() - ) - } answers { expectedString } - - val result = DisplayUtils.getRelativeDateTimeString( - context, - time, - DateUtils.SECOND_IN_MILLIS, - DateUtils.WEEK_IN_MILLIS, - 0 - ) + val expected = formatter.format(Date(time)) - val normalizedResult = result.toString().normalizeResult() - val normalizedExpected = expectedString.normalizeResult() - assertEquals(normalizedExpected, normalizedResult) + assertRelativeDateTimeString(time, expected, DateUtils.SECOND_IN_MILLIS) } @Test fun `getRelativeDateTimeString returns proper relative string for hours ago`() { - every { - DateUtils.getRelativeDateTimeString( - any(), - any(), - any(), - any(), - any() - ) - } answers { "2 hours ago" } - + val expected = "2 hours ago" val time = JANUARY_27_2026 - TWO_HOURS - val result = DisplayUtils.getRelativeDateTimeString( - context, - time, - DateUtils.MINUTE_IN_MILLIS, - DateUtils.WEEK_IN_MILLIS, - 0 - ) - - assert(result.isNotEmpty()) + assertRelativeDateTimeString(time, expected, DateUtils.MINUTE_IN_MILLIS) } @Test fun `getRelativeDateTimeString returns relative string for one week ago`() { - val expectedResult = "Jan 20" - - every { - DateUtils.getRelativeDateTimeString( - any(), - any(), - any(), - any(), - any() - ) - } answers { expectedResult } - + val expected = "Jan 20" val time = JANUARY_27_2026 - ONE_WEEK - val result = DisplayUtils.getRelativeDateTimeString( - context, - time, - DateUtils.MINUTE_IN_MILLIS, - DateUtils.WEEK_IN_MILLIS, - 0 - ) - - assertEquals(expectedResult, result) + assertRelativeDateTimeString(time, expected) } @Test fun `getRelativeDateTimeString returns relative string for one month ago`() { - val expectedResult = "12/28/2025" - - every { - DateUtils.getRelativeDateTimeString( - any(), - any(), - any(), - any(), - any() - ) - } answers { expectedResult } - + val expected = "12/28/2025" val time = JANUARY_27_2026 - ONE_MONTH - val result = DisplayUtils.getRelativeDateTimeString( - context, - time, - DateUtils.DAY_IN_MILLIS, - DateUtils.WEEK_IN_MILLIS, - 0 - ) - - assertEquals(expectedResult, result) + assertRelativeDateTimeString(time, expected, DateUtils.DAY_IN_MILLIS) } @Test fun `getRelativeDateTimeString returns relative string for one year ago`() { - val expectedResult = "1/27/2025" + val expected = "1/27/2025" + val time = JANUARY_27_2026 - ONE_YEAR + + assertRelativeDateTimeString(time, expected, DateUtils.DAY_IN_MILLIS) + } + private fun assertRelativeDateTimeString( + time: Long, + expected: String, + minResolution: Long = DateUtils.MINUTE_IN_MILLIS, + transitionResolution: Long = DateUtils.WEEK_IN_MILLIS + ) { every { DateUtils.getRelativeDateTimeString( any(), @@ -235,22 +147,11 @@ class UploadConversionTest { any(), any() ) - } answers { expectedResult } - - val time = JANUARY_27_2026 - ONE_YEAR - - val result = DisplayUtils.getRelativeDateTimeString( - context, - time, - DateUtils.DAY_IN_MILLIS, - DateUtils.WEEK_IN_MILLIS, - 0 - ) + } answers { expected } - assertEquals(expectedResult, result) + val result = DisplayUtils.getRelativeDateTimeString(context, time, minResolution, transitionResolution, 0) + assertEquals(expected.normalizeResult(), result.toString().normalizeResult()) } - private fun String.normalizeResult(): String { - return replace('\u202F', ' ').replace('\u00A0', ' ') - } + private fun String.normalizeResult(): String = replace('\u202F', ' ').replace('\u00A0', ' ') } From aaeb3bd9f966b221985fc7d63287087ead5bc43d Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Tue, 27 Jan 2026 11:03:44 +0100 Subject: [PATCH 3/3] test: add unit tests for DisplayUtils and UploadEntity conversions Signed-off-by: alperozturk96 --- .../com/nextcloud}/utils/UploadDateTests.kt | 56 +++++++++---------- 1 file changed, 27 insertions(+), 29 deletions(-) rename app/src/{test/java/com/nextcloud/client => androidTest/java/com/nextcloud}/utils/UploadDateTests.kt (78%) diff --git a/app/src/test/java/com/nextcloud/client/utils/UploadDateTests.kt b/app/src/androidTest/java/com/nextcloud/utils/UploadDateTests.kt similarity index 78% rename from app/src/test/java/com/nextcloud/client/utils/UploadDateTests.kt rename to app/src/androidTest/java/com/nextcloud/utils/UploadDateTests.kt index fa27cc6e167f..00177f0f872c 100644 --- a/app/src/test/java/com/nextcloud/client/utils/UploadDateTests.kt +++ b/app/src/androidTest/java/com/nextcloud/utils/UploadDateTests.kt @@ -5,22 +5,24 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -package com.nextcloud.client.utils +package com.nextcloud.utils import android.content.Context import android.text.format.DateUtils +import androidx.test.platform.app.InstrumentationRegistry import com.nextcloud.client.database.entity.UploadEntity import com.nextcloud.client.database.entity.toOCUpload import com.nextcloud.client.database.entity.toUploadEntity -import com.owncloud.android.utils.DisplayUtils -import org.junit.Assert.assertEquals -import org.junit.Assert.assertNotNull -import org.junit.Test import com.owncloud.android.R +import com.owncloud.android.utils.DisplayUtils +import io.mockk.MockKAnnotations import io.mockk.every -import io.mockk.mockk import io.mockk.mockkStatic +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertTrue import org.junit.Before +import org.junit.Test import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @@ -43,12 +45,14 @@ class UploadDateTests { @Before fun setup() { - context = mockk(relaxed = true) - mockkStatic(DateUtils::class) + context = InstrumentationRegistry.getInstrumentation().context + MockKAnnotations.init(this, relaxed = true) + mockkStatic(System::class) + every { System.currentTimeMillis() } returns JANUARY_27_2026 } @Test - fun `UploadEntity converts to OCUpload and back correctly`() { + fun uploadEntityConvertsToOCUploadAndBackCorrectly() { val entity = UploadEntity( id = 123, localPath = "/local/file.txt", @@ -85,15 +89,19 @@ class UploadDateTests { } @Test - fun `getRelativeDateTimeString returns seconds ago for recent past`() { - val expected = "seconds ago" - every { context.getString(R.string.file_list_seconds_ago) } returns expected - - assertRelativeDateTimeString(JANUARY_27_2026 - THIRTY_SECONDS, expected, DateUtils.SECOND_IN_MILLIS) + fun getRelativeDateTimeStringReturnsSecondsAgoForRecentPast() { + val result = DisplayUtils.getRelativeDateTimeString( + context, + JANUARY_27_2026 - THIRTY_SECONDS, + DateUtils.SECOND_IN_MILLIS, + DateUtils.WEEK_IN_MILLIS, + 0 + ) + assertTrue(result.toString() == context.getString(R.string.file_list_seconds_ago)) } @Test - fun `getRelativeDateTimeString returns future as human readable when showFuture is false`() { + fun getRelativeDateTimeStringReturnsFutureAsHumanReadableWhenShowFutureIsFalse() { val formatter = SimpleDateFormat(DATE_FORMATTER_PATTERN, Locale.US) val time = JANUARY_27_2026 + ONE_MINUTE val expected = formatter.format(Date(time)) @@ -102,7 +110,7 @@ class UploadDateTests { } @Test - fun `getRelativeDateTimeString returns proper relative string for hours ago`() { + fun getRelativeDateTimeStringReturnsProperRelativeStringForHoursAgo() { val expected = "2 hours ago" val time = JANUARY_27_2026 - TWO_HOURS @@ -110,7 +118,7 @@ class UploadDateTests { } @Test - fun `getRelativeDateTimeString returns relative string for one week ago`() { + fun getRelativeDateTimeStringReturnsRelativeStringForOneWeekAgo() { val expected = "Jan 20" val time = JANUARY_27_2026 - ONE_WEEK @@ -118,7 +126,7 @@ class UploadDateTests { } @Test - fun `getRelativeDateTimeString returns relative string for one month ago`() { + fun getRelativeDateTimeStringReturnsRelativeStringForOneMonthAgo() { val expected = "12/28/2025" val time = JANUARY_27_2026 - ONE_MONTH @@ -126,7 +134,7 @@ class UploadDateTests { } @Test - fun `getRelativeDateTimeString returns relative string for one year ago`() { + fun getRelativeDateTimeStringReturnsRelativeStringForOneYearAgo() { val expected = "1/27/2025" val time = JANUARY_27_2026 - ONE_YEAR @@ -139,16 +147,6 @@ class UploadDateTests { minResolution: Long = DateUtils.MINUTE_IN_MILLIS, transitionResolution: Long = DateUtils.WEEK_IN_MILLIS ) { - every { - DateUtils.getRelativeDateTimeString( - any(), - any(), - any(), - any(), - any() - ) - } answers { expected } - val result = DisplayUtils.getRelativeDateTimeString(context, time, minResolution, transitionResolution, 0) assertEquals(expected.normalizeResult(), result.toString().normalizeResult()) }