diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index 64e3fb5..9d7c0ea 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -33,6 +33,12 @@ kotlin { sourceSets { commonMain.dependencies { } + commonTest.dependencies { + implementation(kotlin("test")) + } + androidUnitTest.dependencies { + implementation(kotlin("test-junit")) + } } } diff --git a/shared/src/commonTest/kotlin/dev/onexeor/kdownloader/DownloadErrorTest.kt b/shared/src/commonTest/kotlin/dev/onexeor/kdownloader/DownloadErrorTest.kt new file mode 100644 index 0000000..255422d --- /dev/null +++ b/shared/src/commonTest/kotlin/dev/onexeor/kdownloader/DownloadErrorTest.kt @@ -0,0 +1,88 @@ +package dev.onexeor.kdownloader + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNull +import kotlin.test.assertTrue + +class DownloadErrorTest { + + @Test + fun networkErrorHasMessage() { + val error = DownloadError.Network("Connection timeout") + assertEquals("Connection timeout", error.message) + assertNull(error.cause) + } + + @Test + fun networkErrorCanHaveCause() { + val cause = RuntimeException("Underlying error") + val error = DownloadError.Network("Connection failed", cause) + assertEquals("Connection failed", error.message) + assertEquals(cause, error.cause) + } + + @Test + fun httpErrorHasStatusCode() { + val error = DownloadError.Http(404, "Not Found") + assertEquals(404, error.statusCode) + assertEquals("Not Found", error.message) + } + + @Test + fun storageErrorHasMessage() { + val error = DownloadError.Storage("Disk full") + assertEquals("Disk full", error.message) + } + + @Test + fun invalidUrlErrorHasMessage() { + val error = DownloadError.InvalidUrl("Malformed URL: abc") + assertEquals("Malformed URL: abc", error.message) + } + + @Test + fun cancelledErrorHasDefaultMessage() { + val error = DownloadError.Cancelled + assertEquals("Download cancelled", error.message) + } + + @Test + fun unknownErrorHasMessage() { + val error = DownloadError.Unknown("Something went wrong") + assertEquals("Something went wrong", error.message) + } + + @Test + fun errorsCanBeUsedInWhenExpression() { + val errors: List = listOf( + DownloadError.Network("test"), + DownloadError.Http(500, "Server error"), + DownloadError.Storage("test"), + DownloadError.InvalidUrl("test"), + DownloadError.Cancelled, + DownloadError.Unknown("test") + ) + + errors.forEach { error -> + val result = when (error) { + is DownloadError.Network -> "network" + is DownloadError.Http -> "http-${error.statusCode}" + is DownloadError.Storage -> "storage" + is DownloadError.InvalidUrl -> "invalid-url" + is DownloadError.Cancelled -> "cancelled" + is DownloadError.Unknown -> "unknown" + } + assertTrue(result.isNotEmpty()) + } + } + + @Test + fun httpErrorCoversCommonStatusCodes() { + val codes = listOf(400, 401, 403, 404, 500, 502, 503) + codes.forEach { code -> + val error = DownloadError.Http(code, "Error $code") + assertEquals(code, error.statusCode) + } + } +} diff --git a/shared/src/commonTest/kotlin/dev/onexeor/kdownloader/DownloadProgressTest.kt b/shared/src/commonTest/kotlin/dev/onexeor/kdownloader/DownloadProgressTest.kt new file mode 100644 index 0000000..da245f1 --- /dev/null +++ b/shared/src/commonTest/kotlin/dev/onexeor/kdownloader/DownloadProgressTest.kt @@ -0,0 +1,79 @@ +package dev.onexeor.kdownloader + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class DownloadProgressTest { + + @Test + fun zeroProgressHasCorrectDefaults() { + val progress = DownloadProgress.ZERO + assertEquals(0, progress.bytesDownloaded) + assertEquals(-1, progress.totalBytes) + assertEquals(-1, progress.percentage) + } + + @Test + fun isSizeKnownReturnsTrueWhenTotalBytesPositive() { + val progress = DownloadProgress( + bytesDownloaded = 100, + totalBytes = 1000, + percentage = 10 + ) + assertTrue(progress.isSizeKnown) + } + + @Test + fun isSizeKnownReturnsFalseWhenTotalBytesNegative() { + val progress = DownloadProgress( + bytesDownloaded = 100, + totalBytes = -1, + percentage = -1 + ) + assertFalse(progress.isSizeKnown) + } + + @Test + fun isSizeKnownReturnsFalseWhenTotalBytesZero() { + val progress = DownloadProgress( + bytesDownloaded = 0, + totalBytes = 0, + percentage = 0 + ) + assertFalse(progress.isSizeKnown) + } + + @Test + fun hasStartedReturnsTrueWhenBytesDownloaded() { + val progress = DownloadProgress( + bytesDownloaded = 1, + totalBytes = 100, + percentage = 1 + ) + assertTrue(progress.hasStarted) + } + + @Test + fun hasStartedReturnsFalseWhenNoBytesDownloaded() { + val progress = DownloadProgress( + bytesDownloaded = 0, + totalBytes = 100, + percentage = 0 + ) + assertFalse(progress.hasStarted) + } + + @Test + fun progressValuesAreCorrect() { + val progress = DownloadProgress( + bytesDownloaded = 500, + totalBytes = 1000, + percentage = 50 + ) + assertEquals(500, progress.bytesDownloaded) + assertEquals(1000, progress.totalBytes) + assertEquals(50, progress.percentage) + } +} diff --git a/shared/src/commonTest/kotlin/dev/onexeor/kdownloader/DownloadRequestBuilderTest.kt b/shared/src/commonTest/kotlin/dev/onexeor/kdownloader/DownloadRequestBuilderTest.kt new file mode 100644 index 0000000..2677a55 --- /dev/null +++ b/shared/src/commonTest/kotlin/dev/onexeor/kdownloader/DownloadRequestBuilderTest.kt @@ -0,0 +1,100 @@ +package dev.onexeor.kdownloader + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNull +import kotlin.test.assertTrue + +class DownloadRequestBuilderTest { + + @Test + fun builderSetsUrl() { + val request = DownloadRequestBuilder("https://example.com/file.zip").build() + assertEquals("https://example.com/file.zip", request.url) + } + + @Test + fun builderSetsFileName() { + val request = DownloadRequestBuilder("https://example.com/file.zip").apply { + fileName = "custom.zip" + }.build() + assertEquals("custom.zip", request.fileName) + } + + @Test + fun builderSetsDirectory() { + val request = DownloadRequestBuilder("https://example.com/file.zip").apply { + directory = "/downloads" + }.build() + assertEquals("/downloads", request.directory) + } + + @Test + fun builderDefaultsToNoOverwrite() { + val request = DownloadRequestBuilder("https://example.com/file.zip").build() + assertEquals(false, request.overwrite) + } + + @Test + fun overwriteIfExistsSetsOverwriteTrue() { + val request = DownloadRequestBuilder("https://example.com/file.zip").apply { + overwriteIfExists() + }.build() + assertTrue(request.overwrite) + } + + @Test + fun wifiOnlySetsNetworkType() { + val request = DownloadRequestBuilder("https://example.com/file.zip").apply { + wifiOnly() + }.build() + assertEquals(NetworkType.WIFI_ONLY, request.networkType) + } + + @Test + fun headersDslAddsHeaders() { + val request = DownloadRequestBuilder("https://example.com/file.zip").apply { + headers { + "X-Custom" to "value1" + "Accept" to "application/json" + } + }.build() + assertEquals("value1", request.headers["X-Custom"]) + assertEquals("application/json", request.headers["Accept"]) + } + + @Test + fun authBearerSetsAuth() { + val request = DownloadRequestBuilder("https://example.com/file.zip").apply { + auth { + bearer("my-token") + } + }.build() + val auth = request.auth + assertTrue(auth is Auth.Bearer) + assertEquals("my-token", auth.token) + } + + @Test + fun authBasicSetsAuth() { + val request = DownloadRequestBuilder("https://example.com/file.zip").apply { + auth { + basic("user", "pass") + } + }.build() + val auth = request.auth + assertTrue(auth is Auth.Basic) + assertEquals("user", auth.username) + assertEquals("pass", auth.password) + } + + @Test + fun defaultsAreNull() { + val request = DownloadRequestBuilder("https://example.com/file.zip").build() + assertNull(request.fileName) + assertNull(request.directory) + assertNull(request.auth) + assertNull(request.networkType) + assertTrue(request.headers.isEmpty()) + } +} diff --git a/shared/src/commonTest/kotlin/dev/onexeor/kdownloader/DownloadStateTest.kt b/shared/src/commonTest/kotlin/dev/onexeor/kdownloader/DownloadStateTest.kt new file mode 100644 index 0000000..e37c24d --- /dev/null +++ b/shared/src/commonTest/kotlin/dev/onexeor/kdownloader/DownloadStateTest.kt @@ -0,0 +1,70 @@ +package dev.onexeor.kdownloader + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class DownloadStateTest { + + @Test + fun pendingStateIsCorrectType() { + val state: DownloadState = DownloadState.Pending + assertTrue(state is DownloadState.Pending) + } + + @Test + fun downloadingStateContainsProgress() { + val progress = DownloadProgress(50, 100, 50) + val state = DownloadState.Downloading(progress) + assertEquals(progress, state.progress) + } + + @Test + fun pausedStateContainsReason() { + val state = DownloadState.Paused("Waiting for WiFi") + assertEquals("Waiting for WiFi", state.reason) + } + + @Test + fun completedStateContainsFilePath() { + val state = DownloadState.Completed("/path/to/file.zip") + assertEquals("/path/to/file.zip", state.filePath) + } + + @Test + fun failedStateContainsError() { + val error = DownloadError.Network("Connection failed") + val state = DownloadState.Failed(error) + assertEquals(error, state.error) + } + + @Test + fun cancelledStateIsCorrectType() { + val state: DownloadState = DownloadState.Cancelled + assertTrue(state is DownloadState.Cancelled) + } + + @Test + fun statesCanBeUsedInWhenExpression() { + val states = listOf( + DownloadState.Pending, + DownloadState.Downloading(DownloadProgress.ZERO), + DownloadState.Paused("test"), + DownloadState.Completed("/path"), + DownloadState.Failed(DownloadError.Cancelled), + DownloadState.Cancelled + ) + + states.forEach { state -> + val result = when (state) { + is DownloadState.Pending -> "pending" + is DownloadState.Downloading -> "downloading" + is DownloadState.Paused -> "paused" + is DownloadState.Completed -> "completed" + is DownloadState.Failed -> "failed" + is DownloadState.Cancelled -> "cancelled" + } + assertTrue(result.isNotEmpty()) + } + } +} diff --git a/shared/src/commonTest/kotlin/dev/onexeor/kdownloader/KDownloaderConfigTest.kt b/shared/src/commonTest/kotlin/dev/onexeor/kdownloader/KDownloaderConfigTest.kt new file mode 100644 index 0000000..96944a1 --- /dev/null +++ b/shared/src/commonTest/kotlin/dev/onexeor/kdownloader/KDownloaderConfigTest.kt @@ -0,0 +1,42 @@ +package dev.onexeor.kdownloader + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNull + +class KDownloaderConfigTest { + + @Test + fun defaultConfigHasNullDirectory() { + val config = KDownloaderConfig() + assertNull(config.defaultDirectory) + } + + @Test + fun defaultConfigHasAnyNetworkType() { + val config = KDownloaderConfig() + assertEquals(NetworkType.ANY, config.defaultNetworkType) + } + + @Test + fun configCanSetDirectory() { + val config = KDownloaderConfig(defaultDirectory = "Downloads/MyApp") + assertEquals("Downloads/MyApp", config.defaultDirectory) + } + + @Test + fun configCanSetNetworkType() { + val config = KDownloaderConfig(defaultNetworkType = NetworkType.WIFI_ONLY) + assertEquals(NetworkType.WIFI_ONLY, config.defaultNetworkType) + } + + @Test + fun configCanSetBothValues() { + val config = KDownloaderConfig( + defaultDirectory = "custom/path", + defaultNetworkType = NetworkType.WIFI_ONLY + ) + assertEquals("custom/path", config.defaultDirectory) + assertEquals(NetworkType.WIFI_ONLY, config.defaultNetworkType) + } +}