Repository Unit Tests #50
@ -269,6 +269,7 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
private fun getContentFromMercury(customTabsIntent: CustomTabsIntent) {
|
||||
if (repository.isNetworkAvailable()) {
|
||||
binding.progressBar.visibility = View.VISIBLE
|
||||
// TODO: The api should be accessed through the repository
|
||||
AmineB marked this conversation as resolved
Outdated
|
||||
val parser = MercuryApi()
|
||||
|
||||
parser.parseUrl(url).enqueue(
|
||||
|
@ -378,6 +378,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
api.refreshLoginInformation()
|
||||
}
|
||||
|
||||
// TODO: This should be private
|
||||
suspend fun updateApiVersion() {
|
||||
val apiMajorVersion = appSettingsService.getApiVersion()
|
||||
|
||||
@ -389,6 +390,8 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This should be private (since all api calls are made through the repository
|
||||
// no other entity needs to know about the connectivity status)
|
||||
fun isNetworkAvailable() = isConnectionAvailable.value && !offlineOverride
|
||||
|
||||
private fun getDBActions(): List<ACTION> =
|
||||
@ -440,7 +443,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
db.itemsQueries.updateItem(item.datetime, item.title.getHtmlDecoded(), item.content, item.unread, item.starred, item.thumbnail, item.icon, item.link, item.sourcetitle, item.tags.joinToString(","), item.id.toString())
|
||||
|
||||
|
||||
suspend fun tryToCacheItemsAndGetNewOnes(): List<SelfossModel.Item>? {
|
||||
suspend fun tryToCacheItemsAndGetNewOnes(): List<SelfossModel.Item> {
|
||||
try {
|
||||
val newItems = getMaxItemsForBackground(ItemType.UNREAD)
|
||||
val allItems = getMaxItemsForBackground(ItemType.ALL)
|
||||
|
@ -692,6 +692,82 @@ class RepositoryTest() {
|
||||
coVerify(exactly = 1) { api.refreshLoginInformation() }
|
||||
coVerify(exactly = 1) {appSettingsService.refreshLoginInformation("https://test.com/selfoss/", "login", "password")}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cache items`() {
|
||||
coEvery { api.getItems(any(), any(), any(), any(), any(), any(), any()) } returns
|
||||
SelfossModel.StatusAndData(success = true, data = generateTestApiItem())
|
||||
|
||||
val repository = Repository(api, appSettingsService, connectivityStatus, db)
|
||||
repository.tagFilter = SelfossModel.Tag("Tag", "read", 0)
|
||||
repository.sourceFilter = SelfossModel.Source(
|
||||
1,
|
||||
"First source",
|
||||
listOf("Test", "second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
)
|
||||
repository.searchFilter = "search"
|
||||
var items = emptyList<SelfossModel.Item>()
|
||||
runBlocking {
|
||||
items = repository.tryToCacheItemsAndGetNewOnes()
|
||||
}
|
||||
|
||||
coVerify(exactly = 3) { api.getItems(any(), 0, null, null, null, null, 200) }
|
||||
AmineB marked this conversation as resolved
Outdated
AmineB
commented
This should be changed to This should be changed to `coVerify(exactly = 3) { api.getItems(any(), 0, "Tag", 1, "search", null, 200) }`
davidoskky
commented
This function is supposed to store articles for the background; it should store all articles independently of the tags selected by the user in the foreground. This function is supposed to store articles for the background; it should store all articles independently of the tags selected by the user in the foreground.
AmineB
commented
I don't know what you wanted to test. The thing is, passing I don't know what you wanted to test.
The thing is, passing `null, null, null, null` in the function will make it fail, because in your calls, you pass data.
davidoskky
commented
I expect the function to behave differently from how it is currently behaving. Expected behavior: If one of those nulls is substituted by another value, it will not be the last 200 articles that will be stored, but 200 articles filtered according to some external factor. I expect the function to behave differently from how it is currently behaving.
Expected behavior:
When background sync starts, the last 200 articles for each item type are cached.
Thus I expect these 3 calls
getItems("unread", 0, null, null, null, null, 200)
getItems("all", 0, null, null, null, null, 200)
getItems("starred", 0, null, null, null, 200)
If one of those nulls is substituted by another value, it will not be the last 200 articles that will be stored, but 200 articles filtered according to some external factor.
This is not what I would expect as an user, I would expect that the latest articles are always available if I enable background syncronization.
AmineB
commented
Well, this is because you set filters from lines 701 to 711. When using the app, no filter would be set when calling this method, so you'll have what you expect. > If one of those nulls is substituted by another value, it will not be the last 200 articles that will be stored, but 200 articles filtered according to some external factor.
Well, this is because you set filters from lines 701 to 711. When using the app, no filter would be set when calling this method, so you'll have what you expect.
davidoskky
commented
No, filters can be set when this method is called. Imagine this:
Since the repository stores the filter internally, the filter will be set for this background function as well. No, filters can be set when this method is called.
This method should deliberately ignore filters.
Imagine this:
- Open the app
- Select one tag
- The background sync starts at this moment
Since the repository stores the filter internally, the filter will be set for this background function as well.
This function should make the call without any filter even when filters are set in the repository.
AmineB
commented
Ok. So Ok.
So `getMaxItemsForBackground` should be changed, then.
|
||||
assertSame(3, items.size)
|
||||
AmineB marked this conversation as resolved
Outdated
AmineB
commented
You will also need to add `tryToCacheItemsAndGetNewOnes` will only return `1` item as it only returns new items.
You will also need to add `every { db.itemsQueries.transaction(any(), any()) } returns Unit` to the setup.
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cache items but response fails`() {
|
||||
coEvery { api.getItems(any(), any(), any(), any(), any(), any(), any()) } returns
|
||||
SelfossModel.StatusAndData(success = false, data = generateTestApiItem())
|
||||
|
||||
val repository = Repository(api, appSettingsService, connectivityStatus, db)
|
||||
repository.tagFilter = SelfossModel.Tag("Tag", "read", 0)
|
||||
repository.sourceFilter = SelfossModel.Source(
|
||||
1,
|
||||
"First source",
|
||||
listOf("Test", "second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
)
|
||||
repository.searchFilter = "search"
|
||||
var items = emptyList<SelfossModel.Item>()
|
||||
runBlocking {
|
||||
items = repository.tryToCacheItemsAndGetNewOnes()
|
||||
}
|
||||
|
||||
coVerify(exactly = 3) { api.getItems(any(), 0, null, null, null, null, 200) }
|
||||
AmineB marked this conversation as resolved
Outdated
AmineB
commented
This should be This should be `coVerify(exactly = 3) { api.getItems(any(), 0, "Tag", 1, "search", null, 200) }`
davidoskky
commented
As above As above
AmineB
commented
As above. I don't know what you wanted to test. The thing is, passing null, null, null, null in the function will make it fail, because in your calls, you pass data. As above.
I don't know what you wanted to test.
The thing is, passing null, null, null, null in the function will make it fail, because in your calls, you pass data.
|
||||
assertSame(0, items.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `cache items without connection`() {
|
||||
coEvery { api.getItems(any(), any(), any(), any(), any(), any(), any()) } returns
|
||||
SelfossModel.StatusAndData(success = false, data = generateTestApiItem())
|
||||
every { connectivityStatus.isNetworkConnected } returns MutableStateFlow(false)
|
||||
|
||||
val repository = Repository(api, appSettingsService, connectivityStatus, db)
|
||||
repository.tagFilter = SelfossModel.Tag("Tag", "read", 0)
|
||||
repository.sourceFilter = SelfossModel.Source(
|
||||
1,
|
||||
"First source",
|
||||
listOf("Test", "second"),
|
||||
"spouts\\rss\\fulltextrss",
|
||||
"",
|
||||
"d8c92cdb1ef119ea85c4b9205c879ca7.png"
|
||||
)
|
||||
repository.searchFilter = "search"
|
||||
var items = emptyList<SelfossModel.Item>()
|
||||
runBlocking {
|
||||
items = repository.tryToCacheItemsAndGetNewOnes()
|
||||
}
|
||||
|
||||
coVerify(exactly = 0) { api.getItems(any(), 0, null, null, null, null, 200) }
|
||||
assertSame(emptyList<SelfossModel.Item>(), items)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateTestDBItems(item : FakeItemParameters = FakeItemParameters()) : List<ITEM> {
|
||||
|
This is a simple api call to fetch the artcile content. There is no need to put it inside the repository. It is only used here.
Yes, I do understand.
I suggest this edit just because it would allow to keep all information about the connectivity private within the repository and increase incapsulation.
But there is no real significant difference.