mirror of
https://github.com/home-assistant/android
synced 2024-10-02 22:34:46 +00:00
Url improvement (#156)
* Save url with string * throw malformed http url exception if the url is not valid * catch malformed http url exception
This commit is contained in:
parent
f44bb402ab
commit
7ee9dfee4d
|
@ -1,9 +1,8 @@
|
||||||
package io.homeassistant.companion.android.onboarding.manual
|
package io.homeassistant.companion.android.onboarding.manual
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import io.homeassistant.companion.android.domain.MalformedHttpUrlException
|
||||||
import io.homeassistant.companion.android.domain.authentication.AuthenticationUseCase
|
import io.homeassistant.companion.android.domain.authentication.AuthenticationUseCase
|
||||||
import java.net.MalformedURLException
|
|
||||||
import java.net.URL
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -22,18 +21,15 @@ class ManualSetupPresenterImpl @Inject constructor(
|
||||||
|
|
||||||
private val mainScope: CoroutineScope = CoroutineScope(Dispatchers.Main + Job())
|
private val mainScope: CoroutineScope = CoroutineScope(Dispatchers.Main + Job())
|
||||||
|
|
||||||
override fun onClickOk(urlString: String) {
|
override fun onClickOk(url: String) {
|
||||||
val url: URL
|
|
||||||
try {
|
|
||||||
url = URL(urlString)
|
|
||||||
} catch (e: MalformedURLException) {
|
|
||||||
Log.e(TAG, "Unable to parse url", e)
|
|
||||||
view.displayUrlError()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
mainScope.launch {
|
mainScope.launch {
|
||||||
authenticationUseCase.saveUrl(URL(url.protocol, url.host, url.port, ""))
|
try {
|
||||||
|
authenticationUseCase.saveUrl(url)
|
||||||
|
} catch (e: MalformedHttpUrlException) {
|
||||||
|
Log.e(TAG, "Unable to parse url", e)
|
||||||
|
view.displayUrlError()
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
view.urlSaved()
|
view.urlSaved()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package io.homeassistant.companion.android.onboarding.manual
|
package io.homeassistant.companion.android.onboarding.manual
|
||||||
|
|
||||||
|
import io.homeassistant.companion.android.domain.MalformedHttpUrlException
|
||||||
import io.homeassistant.companion.android.domain.authentication.AuthenticationUseCase
|
import io.homeassistant.companion.android.domain.authentication.AuthenticationUseCase
|
||||||
import io.mockk.Called
|
import io.mockk.coEvery
|
||||||
import io.mockk.coVerifyAll
|
import io.mockk.coVerifyAll
|
||||||
|
import io.mockk.just
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
|
import io.mockk.runs
|
||||||
import io.mockk.verify
|
import io.mockk.verify
|
||||||
import java.net.URL
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.test.resetMain
|
import kotlinx.coroutines.test.resetMain
|
||||||
import kotlinx.coroutines.test.setMain
|
import kotlinx.coroutines.test.setMain
|
||||||
|
@ -30,10 +32,11 @@ object ManualSetupPresenterImplSpec : Spek({
|
||||||
describe("on click ok with valid url") {
|
describe("on click ok with valid url") {
|
||||||
beforeEachTest {
|
beforeEachTest {
|
||||||
presenter.onClickOk("https://demo.home-assistant.io:8123/lovelace/default_view?home_assistant=1&true=false")
|
presenter.onClickOk("https://demo.home-assistant.io:8123/lovelace/default_view?home_assistant=1&true=false")
|
||||||
|
coEvery { authenticationUseCase.saveUrl("https://demo.home-assistant.io:8123/lovelace/default_view?home_assistant=1&true=false") } just runs
|
||||||
}
|
}
|
||||||
|
|
||||||
it("should save the url") {
|
it("should save the url") {
|
||||||
coVerifyAll { authenticationUseCase.saveUrl(URL("https://demo.home-assistant.io:8123")) }
|
coVerifyAll { authenticationUseCase.saveUrl("https://demo.home-assistant.io:8123/lovelace/default_view?home_assistant=1&true=false") }
|
||||||
}
|
}
|
||||||
|
|
||||||
it("should notify the listener") {
|
it("should notify the listener") {
|
||||||
|
@ -43,16 +46,14 @@ object ManualSetupPresenterImplSpec : Spek({
|
||||||
|
|
||||||
describe("on click with invalid url") {
|
describe("on click with invalid url") {
|
||||||
beforeEachTest {
|
beforeEachTest {
|
||||||
|
coEvery { authenticationUseCase.saveUrl("home assistant") } throws MalformedHttpUrlException()
|
||||||
presenter.onClickOk("home assistant")
|
presenter.onClickOk("home assistant")
|
||||||
}
|
}
|
||||||
|
|
||||||
it("should not save the url") {
|
it("should save the url") {
|
||||||
coVerifyAll { authenticationUseCase wasNot Called }
|
coVerifyAll { authenticationUseCase.saveUrl("home assistant") }
|
||||||
}
|
}
|
||||||
|
|
||||||
it("shouldn't notify the listener") {
|
|
||||||
verify(exactly = 0) { view.urlSaved() }
|
|
||||||
}
|
|
||||||
it("should display url error") {
|
it("should display url error") {
|
||||||
verify { view.displayUrlError() }
|
verify { view.displayUrlError() }
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,13 @@ package io.homeassistant.companion.android.data.authentication
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import io.homeassistant.companion.android.data.LocalStorage
|
import io.homeassistant.companion.android.data.LocalStorage
|
||||||
|
import io.homeassistant.companion.android.domain.MalformedHttpUrlException
|
||||||
import io.homeassistant.companion.android.domain.authentication.AuthenticationRepository
|
import io.homeassistant.companion.android.domain.authentication.AuthenticationRepository
|
||||||
import io.homeassistant.companion.android.domain.authentication.SessionState
|
import io.homeassistant.companion.android.domain.authentication.SessionState
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Named
|
import javax.inject.Named
|
||||||
|
import okhttp3.HttpUrl
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import org.threeten.bp.Instant
|
import org.threeten.bp.Instant
|
||||||
|
@ -24,8 +26,21 @@ class AuthenticationRepositoryImpl @Inject constructor(
|
||||||
private const val PREF_TOKEN_TYPE = "token_type"
|
private const val PREF_TOKEN_TYPE = "token_type"
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun saveUrl(url: URL) {
|
override suspend fun saveUrl(url: String) {
|
||||||
localStorage.putString(PREF_URL, url.toString())
|
val trimUrl = try {
|
||||||
|
val httpUrl = url.toHttpUrl()
|
||||||
|
HttpUrl.Builder()
|
||||||
|
.scheme(httpUrl.scheme)
|
||||||
|
.host(httpUrl.host)
|
||||||
|
.port(httpUrl.port)
|
||||||
|
.toString()
|
||||||
|
} catch (e: IllegalArgumentException) {
|
||||||
|
throw MalformedHttpUrlException(
|
||||||
|
e.message
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.putString(PREF_URL, trimUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun registerAuthorizationCode(authorizationCode: String) {
|
override suspend fun registerAuthorizationCode(authorizationCode: String) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package io.homeassistant.companion.android.data.authentication
|
package io.homeassistant.companion.android.data.authentication
|
||||||
|
|
||||||
import io.homeassistant.companion.android.data.LocalStorage
|
import io.homeassistant.companion.android.data.LocalStorage
|
||||||
|
import io.homeassistant.companion.android.domain.MalformedHttpUrlException
|
||||||
import io.homeassistant.companion.android.domain.authentication.SessionState
|
import io.homeassistant.companion.android.domain.authentication.SessionState
|
||||||
import io.mockk.Called
|
import io.mockk.Called
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
|
@ -35,13 +36,53 @@ object AuthenticationRepositoryImplSpec : Spek({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("saveUrl") {
|
mapOf(
|
||||||
beforeEachTest {
|
"https://demo.home-assistant.io:8123/lovelace/0/default_view?home_assistant=1&true=false" to "https://demo.home-assistant.io:8123/",
|
||||||
runBlocking { repository.saveUrl(URL("https://demo.home-assistant.io/")) }
|
"https://demo.home-assistant.io/lovelace/0/default_view?home_assistant=1&true=false" to "https://demo.home-assistant.io/",
|
||||||
}
|
"https://demo.home-assistant.io" to "https://demo.home-assistant.io/",
|
||||||
|
"https://192.168.1.1:8123/lovelace/0" to "https://192.168.1.1:8123/",
|
||||||
|
"https://192.168.1.1:8123" to "https://192.168.1.1:8123/",
|
||||||
|
"https://192.168.1.1" to "https://192.168.1.1/"
|
||||||
|
).forEach {
|
||||||
|
describe("save valid url \"${it.key}\"") {
|
||||||
|
beforeEachTest {
|
||||||
|
runBlocking { repository.saveUrl(it.key) }
|
||||||
|
}
|
||||||
|
|
||||||
it("should save url") {
|
it("should save url") {
|
||||||
coVerifyAll { localStorage.putString("url", "https://demo.home-assistant.io/") }
|
coVerifyAll { localStorage.putString("url", it.value) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listOf(
|
||||||
|
"",
|
||||||
|
"home assistant",
|
||||||
|
"http://192.168..132:8123",
|
||||||
|
"http://....:8123",
|
||||||
|
"http://......",
|
||||||
|
"ftp://192.168.1.1"
|
||||||
|
).forEach {
|
||||||
|
describe("save invalid url \"$it\"") {
|
||||||
|
lateinit var throwable: Throwable
|
||||||
|
beforeEachTest {
|
||||||
|
runBlocking {
|
||||||
|
try {
|
||||||
|
repository.saveUrl(it)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throwable = e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it("shouldn't save url") {
|
||||||
|
coVerify(exactly = 0) {
|
||||||
|
localStorage.putString("url", "https://demo.home-assistant.io:8123")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it("should throw an exception") {
|
||||||
|
assertThat(throwable).isInstanceOf(MalformedHttpUrlException::class.java)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package io.homeassistant.companion.android.domain
|
||||||
|
|
||||||
|
import java.net.MalformedURLException
|
||||||
|
|
||||||
|
class MalformedHttpUrlException : MalformedURLException {
|
||||||
|
constructor() : super()
|
||||||
|
constructor(message: String?) : super(message)
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ import java.net.URL
|
||||||
|
|
||||||
interface AuthenticationRepository {
|
interface AuthenticationRepository {
|
||||||
|
|
||||||
suspend fun saveUrl(url: URL)
|
suspend fun saveUrl(url: String)
|
||||||
|
|
||||||
suspend fun registerAuthorizationCode(authorizationCode: String)
|
suspend fun registerAuthorizationCode(authorizationCode: String)
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import java.net.URL
|
||||||
|
|
||||||
interface AuthenticationUseCase {
|
interface AuthenticationUseCase {
|
||||||
|
|
||||||
suspend fun saveUrl(url: URL)
|
suspend fun saveUrl(url: String)
|
||||||
|
|
||||||
suspend fun registerAuthorizationCode(authorizationCode: String)
|
suspend fun registerAuthorizationCode(authorizationCode: String)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ class AuthenticationUseCaseImpl @Inject constructor(
|
||||||
private val authenticationRepository: AuthenticationRepository
|
private val authenticationRepository: AuthenticationRepository
|
||||||
) : AuthenticationUseCase {
|
) : AuthenticationUseCase {
|
||||||
|
|
||||||
override suspend fun saveUrl(url: URL) {
|
override suspend fun saveUrl(url: String) {
|
||||||
authenticationRepository.saveUrl(url)
|
authenticationRepository.saveUrl(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,11 @@ object AuthenticationUseCaseImplSpec : Spek({
|
||||||
|
|
||||||
describe("save url") {
|
describe("save url") {
|
||||||
beforeEachTest {
|
beforeEachTest {
|
||||||
runBlocking { useCase.saveUrl(URL("https://demo.home-assistant.io/")) }
|
runBlocking { useCase.saveUrl("https://demo.home-assistant.io/") }
|
||||||
}
|
}
|
||||||
|
|
||||||
it("should call the repository") {
|
it("should call the repository") {
|
||||||
coVerify { authenticationRepository.saveUrl(URL("https://demo.home-assistant.io/")) }
|
coVerify { authenticationRepository.saveUrl("https://demo.home-assistant.io/") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue