Uri: add resolveLinkUri with tests
This commit is contained in:
parent
fcf12f09d2
commit
fd5471b615
|
@ -1,14 +1,46 @@
|
|||
package dev.lowrespalmtree.comet
|
||||
|
||||
import dev.lowrespalmtree.comet.utils.*
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
/** Test utils.Uri functions. Runs of the device due to the Uri functions being Android-only .*/
|
||||
class UriUtilsTest {
|
||||
@Test
|
||||
fun resolveLinkUri() {
|
||||
// Absolute URLs.
|
||||
assertEquals(
|
||||
"gemini://example.com/",
|
||||
resolveLinkUri("gemini://example.com", "gemini://dece.space/").toString()
|
||||
)
|
||||
// Relative links.
|
||||
assertEquals(
|
||||
"gemini://example.com/",
|
||||
resolveLinkUri(".", "gemini://example.com/").toString()
|
||||
)
|
||||
assertEquals(
|
||||
"gemini://example.com/",
|
||||
resolveLinkUri("..", "gemini://example.com/").toString()
|
||||
)
|
||||
assertEquals(
|
||||
"gemini://example.com/page",
|
||||
resolveLinkUri("./page", "gemini://example.com/").toString()
|
||||
)
|
||||
assertEquals(
|
||||
"gemini://example.com/page",
|
||||
resolveLinkUri("page", "gemini://example.com/").toString()
|
||||
)
|
||||
assertEquals(
|
||||
"gemini://example.com/page.com",
|
||||
resolveLinkUri("page.com", "gemini://example.com/").toString()
|
||||
)
|
||||
// Scheme-less URLs.
|
||||
assertEquals(
|
||||
"gemini://someone.smol.pub/somepage",
|
||||
resolveLinkUri("//someone.smol.pub/somepage", "gemini://smol.pub/feed").toString()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun joinUrls() {
|
||||
assertEquals(
|
||||
|
|
|
@ -20,6 +20,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||
import dev.lowrespalmtree.comet.databinding.FragmentPageViewBinding
|
||||
import dev.lowrespalmtree.comet.utils.isConnectedToNetwork
|
||||
import dev.lowrespalmtree.comet.utils.joinUrls
|
||||
import dev.lowrespalmtree.comet.utils.resolveLinkUri
|
||||
import dev.lowrespalmtree.comet.utils.toGeminiUri
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
|
||||
|
@ -107,13 +108,7 @@ class PageFragment : Fragment(), PageAdapter.Listener {
|
|||
return
|
||||
}
|
||||
|
||||
var uri = Uri.parse(url)
|
||||
if (!uri.isAbsolute) {
|
||||
uri = if (!base.isNullOrEmpty()) joinUrls(base, url) else toGeminiUri(uri)
|
||||
} else if (uri.scheme == "gemini" && uri.path.isNullOrEmpty()) {
|
||||
uri = uri.buildUpon().path("/").build()
|
||||
}
|
||||
|
||||
val uri = resolveLinkUri(url, base)
|
||||
when (uri.scheme) {
|
||||
"gemini" -> vm.sendGeminiRequest(uri, requireContext())
|
||||
else -> openUnknownScheme(uri)
|
||||
|
|
|
@ -9,6 +9,7 @@ import androidx.lifecycle.ViewModel
|
|||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.preference.PreferenceManager
|
||||
import dev.lowrespalmtree.comet.utils.joinUrls
|
||||
import dev.lowrespalmtree.comet.utils.resolveLinkUri
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.onSuccess
|
||||
import java.net.ConnectException
|
||||
|
@ -163,9 +164,7 @@ class PageViewModel(@Suppress("unused") private val savedStateHandle: SavedState
|
|||
lineChannelResult.onSuccess { line ->
|
||||
if (line is LinkLine) {
|
||||
// Mark visited links here as we have a access to the history.
|
||||
val fullUrl =
|
||||
if (Uri.parse(line.url).isAbsolute) line.url
|
||||
else joinUrls(uriString, line.url).toString()
|
||||
val fullUrl = resolveLinkUri(line.url, uriString).toString()
|
||||
if (History.contains(fullUrl))
|
||||
line.visited = true
|
||||
}
|
||||
|
|
|
@ -2,6 +2,26 @@ package dev.lowrespalmtree.comet.utils
|
|||
|
||||
import android.net.Uri
|
||||
|
||||
/**
|
||||
* Resolve the URI of a link found on a page.
|
||||
*
|
||||
* Links can take various forms: absolute links to a page on a capsule, relative links on the same
|
||||
* capsule, but also fancy scheme-less absolute URLs (i.e. starting with "//") for cross-protocol
|
||||
* linking. This function returns the resolved URI from any type of link, opt. using current URL.
|
||||
*/
|
||||
fun resolveLinkUri(url: String, base: String?): Uri {
|
||||
var uri = Uri.parse(url)
|
||||
if (!uri.isAbsolute) {
|
||||
uri =
|
||||
if (url.startsWith("//")) uri.buildUpon().scheme("gemini").build()
|
||||
else if (!base.isNullOrEmpty()) joinUrls(base, url)
|
||||
else toGeminiUri(uri)
|
||||
} else if (uri.scheme == "gemini" && uri.path.isNullOrEmpty()) {
|
||||
uri = uri.buildUpon().path("/").build()
|
||||
}
|
||||
return uri
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a relative URI to an absolute Gemini URI
|
||||
*
|
||||
|
|
Reference in a new issue