Uri: add resolveLinkUri with tests
This commit is contained in:
parent
fcf12f09d2
commit
fd5471b615
|
@ -1,14 +1,46 @@
|
||||||
package dev.lowrespalmtree.comet
|
package dev.lowrespalmtree.comet
|
||||||
|
|
||||||
|
import dev.lowrespalmtree.comet.utils.*
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
/**
|
/** Test utils.Uri functions. Runs of the device due to the Uri functions being Android-only .*/
|
||||||
* Example local unit test, which will execute on the development machine (host).
|
|
||||||
*
|
|
||||||
* See [testing documentation](http://d.android.com/tools/testing).
|
|
||||||
*/
|
|
||||||
class UriUtilsTest {
|
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
|
@Test
|
||||||
fun joinUrls() {
|
fun joinUrls() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
|
|
|
@ -20,6 +20,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import dev.lowrespalmtree.comet.databinding.FragmentPageViewBinding
|
import dev.lowrespalmtree.comet.databinding.FragmentPageViewBinding
|
||||||
import dev.lowrespalmtree.comet.utils.isConnectedToNetwork
|
import dev.lowrespalmtree.comet.utils.isConnectedToNetwork
|
||||||
import dev.lowrespalmtree.comet.utils.joinUrls
|
import dev.lowrespalmtree.comet.utils.joinUrls
|
||||||
|
import dev.lowrespalmtree.comet.utils.resolveLinkUri
|
||||||
import dev.lowrespalmtree.comet.utils.toGeminiUri
|
import dev.lowrespalmtree.comet.utils.toGeminiUri
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
|
||||||
|
@ -107,13 +108,7 @@ class PageFragment : Fragment(), PageAdapter.Listener {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var uri = Uri.parse(url)
|
val uri = resolveLinkUri(url, base)
|
||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
when (uri.scheme) {
|
when (uri.scheme) {
|
||||||
"gemini" -> vm.sendGeminiRequest(uri, requireContext())
|
"gemini" -> vm.sendGeminiRequest(uri, requireContext())
|
||||||
else -> openUnknownScheme(uri)
|
else -> openUnknownScheme(uri)
|
||||||
|
|
|
@ -9,6 +9,7 @@ import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import dev.lowrespalmtree.comet.utils.joinUrls
|
import dev.lowrespalmtree.comet.utils.joinUrls
|
||||||
|
import dev.lowrespalmtree.comet.utils.resolveLinkUri
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.channels.onSuccess
|
import kotlinx.coroutines.channels.onSuccess
|
||||||
import java.net.ConnectException
|
import java.net.ConnectException
|
||||||
|
@ -163,9 +164,7 @@ class PageViewModel(@Suppress("unused") private val savedStateHandle: SavedState
|
||||||
lineChannelResult.onSuccess { line ->
|
lineChannelResult.onSuccess { line ->
|
||||||
if (line is LinkLine) {
|
if (line is LinkLine) {
|
||||||
// Mark visited links here as we have a access to the history.
|
// Mark visited links here as we have a access to the history.
|
||||||
val fullUrl =
|
val fullUrl = resolveLinkUri(line.url, uriString).toString()
|
||||||
if (Uri.parse(line.url).isAbsolute) line.url
|
|
||||||
else joinUrls(uriString, line.url).toString()
|
|
||||||
if (History.contains(fullUrl))
|
if (History.contains(fullUrl))
|
||||||
line.visited = true
|
line.visited = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,26 @@ package dev.lowrespalmtree.comet.utils
|
||||||
|
|
||||||
import android.net.Uri
|
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
|
* Transform a relative URI to an absolute Gemini URI
|
||||||
*
|
*
|
||||||
|
|
Reference in a new issue