From 2c63c1ab94c7ecad41f43ece088b4ea5c617220e Mon Sep 17 00:00:00 2001 From: Patrick Honkonen <1883101+SaintPatrck@users.noreply.github.com> Date: Tue, 11 Feb 2025 18:06:17 -0500 Subject: [PATCH] [PM-14936] Move `prefixHttpsIfNecessaryOrNull` to `StringExtensions` (#4709) --- .../environment/EnvironmentViewModel.kt | 12 +--- .../ui/platform/base/util/StringExtensions.kt | 11 ++++ .../base/util/StringExtensionsTest.kt | 64 +++++++++++++++++++ 3 files changed, 76 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentViewModel.kt index 6e7e9593db6..3c14622e935 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentViewModel.kt @@ -19,6 +19,7 @@ import com.x8bit.bitwarden.ui.platform.base.util.Text import com.x8bit.bitwarden.ui.platform.base.util.asText import com.x8bit.bitwarden.ui.platform.base.util.isValidUri import com.x8bit.bitwarden.ui.platform.base.util.orNullIfBlank +import com.x8bit.bitwarden.ui.platform.base.util.prefixHttpsIfNecessaryOrNull import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager import com.x8bit.bitwarden.ui.platform.manager.keychain.model.PrivateKeyAliasSelectionResult import dagger.hilt.android.lifecycle.HiltViewModel @@ -594,14 +595,3 @@ sealed class EnvironmentAction { ) : Internal() } } - -/** - * If the given [String] is a valid URI, "https://" will be appended if it is not already present. - * Otherwise `null` will be returned. - */ -private fun String.prefixHttpsIfNecessaryOrNull(): String? = - when { - this.isBlank() || !this.isValidUri() -> null - "http://" in this || "https://" in this -> this - else -> "https://$this" - } diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/base/util/StringExtensions.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/base/util/StringExtensions.kt index 70b5d2300a7..6cbb0c48eaf 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/base/util/StringExtensions.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/base/util/StringExtensions.kt @@ -204,3 +204,14 @@ fun String.removeDiacritics(): String = Normalizer.normalize(this, Normalizer.Form.NFKD), "", ) + +/** + * If the given [String] is a valid URI, "https://" will be appended if it is not already present. + * Otherwise `null` will be returned. + */ +fun String.prefixHttpsIfNecessaryOrNull(): String? = + when { + this.isBlank() || !this.isValidUri() -> null + "http://" in this || "https://" in this -> this + else -> "https://$this" + } diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/platform/base/util/StringExtensionsTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/platform/base/util/StringExtensionsTest.kt index 3cf2cdd2819..10a56c373db 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/platform/base/util/StringExtensionsTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/platform/base/util/StringExtensionsTest.kt @@ -141,4 +141,68 @@ class StringExtensionsTest { val result = "áéíóů".removeDiacritics() assertEquals("aeiou", result) } + + @Test + fun `prefixHttpsIfNecessaryOrNull should prefix https when URI is valid and no scheme`() { + val uri = "example.com" + val expected = "https://$uri" + val actual = uri.prefixHttpsIfNecessaryOrNull() + + assertEquals(expected, actual) + } + + @Test + fun `prefixHttpsIfNecessaryOrNull should return null when URI is empty string`() { + val uri = "" + assertNull(uri.prefixHttpsIfNecessaryOrNull()) + } + + @Test + fun `prefixHttpsIfNecessaryOrNull should return null when URI is whitespace string`() { + val uri = " " + assertNull(uri.prefixHttpsIfNecessaryOrNull()) + } + + @Test + fun `prefixHttpsIfNecessaryOrNull should return null when URI is invalid`() { + val invalidUri = "invalid uri" + assertNull(invalidUri.prefixHttpsIfNecessaryOrNull()) + } + + @Test + fun `prefixHttpsIfNecessaryOrNull should return URI unchanged when scheme is http`() { + val uri = "http://example.com" + val actual = uri.prefixHttpsIfNecessaryOrNull() + assertEquals(uri, actual) + } + + @Test + fun `prefixHttpsIfNecessaryOrNull should return URI unchanged when scheme is https`() { + val uri = "https://example.com" + val actual = uri.prefixHttpsIfNecessaryOrNull() + assertEquals(uri, actual) + } + + @Test + fun `prefixHttpsIfNecessaryOrNull with long valid URI without scheme`() { + val uri = "longexamplewithlots.of.subdomains.com" + val expected = "https://$uri" + val actual = uri.prefixHttpsIfNecessaryOrNull() + assertEquals(expected, actual) + } + + @Test + fun `prefixHttpsIfNecessaryOrNull should return null when uri contains special characters`() { + val uri = "example-special!@#$%^&*()_+{}[].com" + val actual = uri.prefixHttpsIfNecessaryOrNull() + assertNull(actual) + } + + @Test + fun `prefixHttpsIfNecessaryOrNull should prefix URI when it contains numbers and letters`() { + val uri = "example1234567890.com" + val expected = "https://$uri" + val actual = uri.prefixHttpsIfNecessaryOrNull() + assertEquals(expected, actual) + } }