This commit is contained in:
parent
527830a5ae
commit
7cfd17231a
@ -426,17 +426,7 @@ class RepositoryTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun get_tags_with_items_caching_disabled() {
|
fun get_tags_with_items_caching_disabled() {
|
||||||
val tags = listOf(
|
val (tags, _) = prepareTags()
|
||||||
SelfossModel.Tag("test", "red", 6),
|
|
||||||
SelfossModel.Tag("second", "yellow", 0)
|
|
||||||
)
|
|
||||||
val tagsDB = listOf(
|
|
||||||
TAG("test_DB", "red", 6),
|
|
||||||
TAG("second_DB", "yellow", 0)
|
|
||||||
)
|
|
||||||
|
|
||||||
coEvery { api.tags() } returns StatusAndData(success = true, data = tags)
|
|
||||||
coEvery { db.tagsQueries.tags().executeAsList() } returns tagsDB
|
|
||||||
every { appSettingsService.isUpdateSourcesEnabled() } returns true
|
every { appSettingsService.isUpdateSourcesEnabled() } returns true
|
||||||
every { appSettingsService.isItemCachingEnabled() } returns false
|
every { appSettingsService.isItemCachingEnabled() } returns false
|
||||||
|
|
||||||
@ -510,17 +500,7 @@ class RepositoryTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun get_tags_without_connection_and_items_caching_disabled() {
|
fun get_tags_without_connection_and_items_caching_disabled() {
|
||||||
val tags = listOf(
|
prepareTags()
|
||||||
SelfossModel.Tag("test", "red", 6),
|
|
||||||
SelfossModel.Tag("second", "yellow", 0)
|
|
||||||
)
|
|
||||||
val tagsDB = listOf(
|
|
||||||
TAG("test_DB", "red", 6),
|
|
||||||
TAG("second_DB", "yellow", 0)
|
|
||||||
)
|
|
||||||
|
|
||||||
coEvery { api.tags() } returns StatusAndData(success = true, data = tags)
|
|
||||||
coEvery { db.tagsQueries.tags().executeAsList() } returns tagsDB
|
|
||||||
every { appSettingsService.isItemCachingEnabled() } returns false
|
every { appSettingsService.isItemCachingEnabled() } returns false
|
||||||
every { appSettingsService.isUpdateSourcesEnabled() } returns true
|
every { appSettingsService.isUpdateSourcesEnabled() } returns true
|
||||||
|
|
||||||
@ -565,17 +545,7 @@ class RepositoryTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun get_tags_without_connection_and_sources_update_and_items_caching_disabled() {
|
fun get_tags_without_connection_and_sources_update_and_items_caching_disabled() {
|
||||||
val tags = listOf(
|
val (_, tagsDB) = prepareTags()
|
||||||
SelfossModel.Tag("test", "red", 6),
|
|
||||||
SelfossModel.Tag("second", "yellow", 0)
|
|
||||||
)
|
|
||||||
val tagsDB = listOf(
|
|
||||||
TAG("test_DB", "red", 6),
|
|
||||||
TAG("second_DB", "yellow", 0)
|
|
||||||
)
|
|
||||||
|
|
||||||
coEvery { api.tags() } returns StatusAndData(success = true, data = tags)
|
|
||||||
coEvery { db.tagsQueries.tags().executeAsList() } returns tagsDB
|
|
||||||
every { appSettingsService.isUpdateSourcesEnabled() } returns false
|
every { appSettingsService.isUpdateSourcesEnabled() } returns false
|
||||||
every { appSettingsService.isItemCachingEnabled() } returns false
|
every { appSettingsService.isItemCachingEnabled() } returns false
|
||||||
|
|
||||||
@ -590,8 +560,36 @@ class RepositoryTest {
|
|||||||
verify(atLeast = 1) { db.tagsQueries.tags().executeAsList() }
|
verify(atLeast = 1) { db.tagsQueries.tags().executeAsList() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun prepareTags(): Pair<List<SelfossModel.Tag>, List<TAG>> {
|
||||||
|
val tags = listOf(
|
||||||
|
SelfossModel.Tag("test", "red", 6),
|
||||||
|
SelfossModel.Tag("second", "yellow", 0)
|
||||||
|
)
|
||||||
|
val tagsDB = listOf(
|
||||||
|
TAG("test_DB", "red", 6),
|
||||||
|
TAG("second_DB", "yellow", 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
coEvery { api.tags() } returns StatusAndData(success = true, data = tags)
|
||||||
|
coEvery { db.tagsQueries.tags().executeAsList() } returns tagsDB
|
||||||
|
return Pair(tags, tagsDB)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun get_sources() {
|
fun get_sources() {
|
||||||
|
val (sources, sourcesDB) = prepareSources()
|
||||||
|
initializeRepository()
|
||||||
|
var testSources: List<SelfossModel.Source>?
|
||||||
|
runBlocking {
|
||||||
|
testSources = repository.getSources()
|
||||||
|
}
|
||||||
|
|
||||||
|
assertSame(sources, testSources)
|
||||||
|
assertNotEquals(sourcesDB.map { it.toView() }, testSources)
|
||||||
|
coVerify(exactly = 1) { api.sources() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun prepareSources(): Pair<ArrayList<SelfossModel.Source>, List<SOURCE>> {
|
||||||
val sources = arrayListOf(
|
val sources = arrayListOf(
|
||||||
SelfossModel.Source(
|
SelfossModel.Source(
|
||||||
1,
|
1,
|
||||||
@ -631,15 +629,7 @@ class RepositoryTest {
|
|||||||
|
|
||||||
coEvery { api.sources() } returns StatusAndData(success = true, data = sources)
|
coEvery { api.sources() } returns StatusAndData(success = true, data = sources)
|
||||||
every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB
|
every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB
|
||||||
initializeRepository()
|
return Pair(sources, sourcesDB)
|
||||||
var testSources: List<SelfossModel.Source>?
|
|
||||||
runBlocking {
|
|
||||||
testSources = repository.getSources()
|
|
||||||
}
|
|
||||||
|
|
||||||
assertSame(sources, testSources)
|
|
||||||
assertNotEquals(sourcesDB.map { it.toView() }, testSources)
|
|
||||||
coVerify(exactly = 1) { api.sources() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -809,45 +799,7 @@ class RepositoryTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun get_sources_without_connection() {
|
fun get_sources_without_connection() {
|
||||||
val sources = arrayListOf(
|
val (_, sourcesDB) = prepareSources()
|
||||||
SelfossModel.Source(
|
|
||||||
1,
|
|
||||||
"First source",
|
|
||||||
listOf("Test", "second"),
|
|
||||||
"spouts\\rss\\fulltextrss",
|
|
||||||
"",
|
|
||||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
|
||||||
),
|
|
||||||
SelfossModel.Source(
|
|
||||||
2,
|
|
||||||
"Second source",
|
|
||||||
listOf("second"),
|
|
||||||
"spouts\\rss\\fulltextrss",
|
|
||||||
"",
|
|
||||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
val sourcesDB = listOf(
|
|
||||||
SOURCE(
|
|
||||||
"1",
|
|
||||||
"First DB source",
|
|
||||||
"Test,second",
|
|
||||||
"spouts\\rss\\fulltextrss",
|
|
||||||
"",
|
|
||||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
|
||||||
),
|
|
||||||
SOURCE(
|
|
||||||
"2",
|
|
||||||
"Second source",
|
|
||||||
"second",
|
|
||||||
"spouts\\rss\\fulltextrss",
|
|
||||||
"",
|
|
||||||
"b3aa8a664d08eb15d6ff1db2fa83e0d9.png"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
coEvery { api.sources() } returns StatusAndData(success = true, data = sources)
|
|
||||||
every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB
|
|
||||||
initializeRepository(MutableStateFlow(false))
|
initializeRepository(MutableStateFlow(false))
|
||||||
var testSources: List<SelfossModel.Source>?
|
var testSources: List<SelfossModel.Source>?
|
||||||
runBlocking {
|
runBlocking {
|
||||||
|
@ -1,15 +1,6 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.model
|
package bou.amine.apps.readerforselfossv2.model
|
||||||
|
|
||||||
import bou.amine.apps.readerforselfossv2.utils.DateUtils
|
|
||||||
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
|
|
||||||
import kotlinx.serialization.KSerializer
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
|
||||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
|
||||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
|
||||||
import kotlinx.serialization.encoding.Decoder
|
|
||||||
import kotlinx.serialization.encoding.Encoder
|
|
||||||
import kotlinx.serialization.json.*
|
|
||||||
|
|
||||||
class MercuryModel {
|
class MercuryModel {
|
||||||
|
|
||||||
@ -20,138 +11,4 @@ class MercuryModel {
|
|||||||
val lead_image_url: String?,
|
val lead_image_url: String?,
|
||||||
val url: String
|
val url: String
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class Tag(
|
|
||||||
val tag: String,
|
|
||||||
val color: String,
|
|
||||||
val unread: Int
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
class Stats(
|
|
||||||
val total: Int,
|
|
||||||
val unread: Int,
|
|
||||||
val starred: Int
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class Spout(
|
|
||||||
val name: String,
|
|
||||||
val description: String
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class ApiVersion(
|
|
||||||
val version: String?,
|
|
||||||
val apiversion: String?
|
|
||||||
) {
|
|
||||||
fun getApiMajorVersion() : Int {
|
|
||||||
var versionNumber = 0
|
|
||||||
if (apiversion != null) {
|
|
||||||
versionNumber = apiversion.substringBefore(".").toInt()
|
|
||||||
}
|
|
||||||
return versionNumber
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class Source(
|
|
||||||
val id: Int,
|
|
||||||
val title: String,
|
|
||||||
@Serializable(with = TagsListSerializer::class)
|
|
||||||
val tags: List<String>,
|
|
||||||
val spout: String,
|
|
||||||
val error: String,
|
|
||||||
val icon: String?
|
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class Item(
|
|
||||||
val id: Int,
|
|
||||||
val datetime: String,
|
|
||||||
val title: String,
|
|
||||||
val content: String,
|
|
||||||
@Serializable(with = BooleanSerializer::class)
|
|
||||||
var unread: Boolean,
|
|
||||||
@Serializable(with = BooleanSerializer::class)
|
|
||||||
var starred: Boolean,
|
|
||||||
val thumbnail: String?,
|
|
||||||
val icon: String?,
|
|
||||||
val link: String,
|
|
||||||
val sourcetitle: String,
|
|
||||||
@Serializable(with = TagsListSerializer::class)
|
|
||||||
val tags: List<String>
|
|
||||||
) {
|
|
||||||
// TODO: maybe find a better way to handle these kind of urls
|
|
||||||
fun getLinkDecoded(): String {
|
|
||||||
var stringUrl: String
|
|
||||||
stringUrl =
|
|
||||||
if (link.startsWith("http://news.google.com/news/") || link.startsWith("https://news.google.com/news/")) {
|
|
||||||
if (link.contains("&url=")) {
|
|
||||||
link.substringAfter("&url=")
|
|
||||||
} else {
|
|
||||||
this.link.replace("&", "&")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.link.replace("&", "&")
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle :443 => https
|
|
||||||
if (stringUrl.contains(":443")) {
|
|
||||||
stringUrl = stringUrl.replace(":443", "").replace("http://", "https://")
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle url not starting with http
|
|
||||||
if (stringUrl.startsWith("//")) {
|
|
||||||
stringUrl = "http:$stringUrl"
|
|
||||||
}
|
|
||||||
|
|
||||||
return stringUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
fun sourceAndDateText(): String =
|
|
||||||
this.sourcetitle.getHtmlDecoded() + DateUtils.parseRelativeDate(this.datetime)
|
|
||||||
|
|
||||||
fun toggleStar(): Item {
|
|
||||||
this.starred = !this.starred
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: this seems to be super slow.
|
|
||||||
object TagsListSerializer : KSerializer<List<String>> {
|
|
||||||
override fun deserialize(decoder: Decoder): List<String> {
|
|
||||||
return when(val json = ((decoder as JsonDecoder).decodeJsonElement())) {
|
|
||||||
is JsonArray -> json.toList().map { it.toString() }
|
|
||||||
else -> json.toString().split(",")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override val descriptor: SerialDescriptor
|
|
||||||
get() = PrimitiveSerialDescriptor("tags", PrimitiveKind.STRING)
|
|
||||||
|
|
||||||
override fun serialize(encoder: Encoder, value: List<String>) {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object BooleanSerializer : KSerializer<Boolean> {
|
|
||||||
override fun deserialize(decoder: Decoder): Boolean {
|
|
||||||
val json = ((decoder as JsonDecoder).decodeJsonElement()).jsonPrimitive
|
|
||||||
return if (json.booleanOrNull != null) {
|
|
||||||
json.boolean
|
|
||||||
} else {
|
|
||||||
json.int == 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override val descriptor: SerialDescriptor
|
|
||||||
get() = PrimitiveSerialDescriptor("b", PrimitiveKind.BOOLEAN)
|
|
||||||
|
|
||||||
override fun serialize(encoder: Encoder, value: Boolean) {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -229,36 +229,14 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
): SuccessResponse =
|
): SuccessResponse =
|
||||||
maybeResponse(
|
maybeResponse(
|
||||||
if (appSettingsService.getApiVersion() > 1) {
|
if (appSettingsService.getApiVersion() > 1) {
|
||||||
createSource2(title, url, spout, tags, filter)
|
createSource("tags[]", title, url, spout, tags, filter)
|
||||||
} else {
|
} else {
|
||||||
createSource(title, url, spout, tags, filter)
|
createSource("tags", title, url, spout, tags, filter)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
private suspend fun createSource(
|
private suspend fun createSource(
|
||||||
title: String,
|
tagsParamName: String,
|
||||||
url: String,
|
|
||||||
spout: String,
|
|
||||||
tags: String,
|
|
||||||
filter: String
|
|
||||||
): HttpResponse =
|
|
||||||
client.submitForm(
|
|
||||||
url = url("/source"),
|
|
||||||
formParameters = Parameters.build {
|
|
||||||
// TODO: test this
|
|
||||||
if (!shouldHavePostLogin()) {
|
|
||||||
append("username", appSettingsService.getUserName())
|
|
||||||
append("password", appSettingsService.getPassword())
|
|
||||||
}
|
|
||||||
append("title", title)
|
|
||||||
append("url", url)
|
|
||||||
append("spout", spout)
|
|
||||||
append("tags", tags)
|
|
||||||
append("filter", filter)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
private suspend fun createSource2(
|
|
||||||
title: String,
|
title: String,
|
||||||
url: String,
|
url: String,
|
||||||
spout: String,
|
spout: String,
|
||||||
@ -275,7 +253,7 @@ class SelfossApi(private val appSettingsService: AppSettingsService) {
|
|||||||
append("title", title)
|
append("title", title)
|
||||||
append("url", url)
|
append("url", url)
|
||||||
append("spout", spout)
|
append("spout", spout)
|
||||||
append("tags[]", tags)
|
append(tagsParamName, tags)
|
||||||
append("filter", filter)
|
append("filter", filter)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user