|
|
@ -11,6 +11,8 @@ import io.mockk.mockk
|
|
|
|
import io.mockk.spyk
|
|
|
|
import io.mockk.spyk
|
|
|
|
import io.mockk.verify
|
|
|
|
import io.mockk.verify
|
|
|
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
|
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
|
|
|
|
|
|
import kotlinx.coroutines.flow.Flow
|
|
|
|
|
|
|
|
import kotlinx.coroutines.flow.flow
|
|
|
|
import kotlinx.coroutines.flow.flowOf
|
|
|
|
import kotlinx.coroutines.flow.flowOf
|
|
|
|
import kotlinx.coroutines.test.TestCoroutineScope
|
|
|
|
import kotlinx.coroutines.test.TestCoroutineScope
|
|
|
|
import mozilla.components.service.pocket.PocketRecommendedStory
|
|
|
|
import mozilla.components.service.pocket.PocketRecommendedStory
|
|
|
@ -59,6 +61,7 @@ class PocketUpdatesMiddlewareTest {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
@Test
|
|
|
|
|
|
|
|
@Suppress("UNCHECKED_CAST")
|
|
|
|
fun `WHEN PocketStoriesCategoriesChange is dispatched THEN intercept and dispatch PocketStoriesCategoriesSelectionsChange`() {
|
|
|
|
fun `WHEN PocketStoriesCategoriesChange is dispatched THEN intercept and dispatch PocketStoriesCategoriesSelectionsChange`() {
|
|
|
|
val persistedSelectedCategory: SelectedPocketStoriesCategory = mockk {
|
|
|
|
val persistedSelectedCategory: SelectedPocketStoriesCategory = mockk {
|
|
|
|
every { name } returns "testCategory"
|
|
|
|
every { name } returns "testCategory"
|
|
|
@ -67,9 +70,10 @@ class PocketUpdatesMiddlewareTest {
|
|
|
|
val persistedSelectedCategories: SelectedPocketStoriesCategories = mockk {
|
|
|
|
val persistedSelectedCategories: SelectedPocketStoriesCategories = mockk {
|
|
|
|
every { valuesList } returns mutableListOf(persistedSelectedCategory)
|
|
|
|
every { valuesList } returns mutableListOf(persistedSelectedCategory)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
val dataStore: DataStore<SelectedPocketStoriesCategories> = mockk {
|
|
|
|
val dataStore: DataStore<SelectedPocketStoriesCategories> =
|
|
|
|
every { data } returns flowOf(persistedSelectedCategories)
|
|
|
|
mockk<FakeDataStore<SelectedPocketStoriesCategories>>(relaxed = true) {
|
|
|
|
}
|
|
|
|
every { data } returns flowOf(persistedSelectedCategories)
|
|
|
|
|
|
|
|
} as DataStore<SelectedPocketStoriesCategories>
|
|
|
|
val currentCategories = listOf(mockk<PocketRecommendedStoriesCategory>())
|
|
|
|
val currentCategories = listOf(mockk<PocketRecommendedStoriesCategory>())
|
|
|
|
val pocketMiddleware = PocketUpdatesMiddleware(TestCoroutineScope(), mockk(), dataStore)
|
|
|
|
val pocketMiddleware = PocketUpdatesMiddleware(TestCoroutineScope(), mockk(), dataStore)
|
|
|
|
val homeStore = spyk(
|
|
|
|
val homeStore = spyk(
|
|
|
@ -96,10 +100,13 @@ class PocketUpdatesMiddlewareTest {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
@Test
|
|
|
|
|
|
|
|
@Suppress("UNCHECKED_CAST")
|
|
|
|
fun `WHEN SelectPocketStoriesCategory is dispatched THEN persist details in DataStore`() {
|
|
|
|
fun `WHEN SelectPocketStoriesCategory is dispatched THEN persist details in DataStore`() {
|
|
|
|
val categ1 = PocketRecommendedStoriesCategory("categ1")
|
|
|
|
val categ1 = PocketRecommendedStoriesCategory("categ1")
|
|
|
|
val categ2 = PocketRecommendedStoriesCategory("categ2")
|
|
|
|
val categ2 = PocketRecommendedStoriesCategory("categ2")
|
|
|
|
val dataStore: DataStore<SelectedPocketStoriesCategories> = mockk(relaxed = true)
|
|
|
|
val dataStore: DataStore<SelectedPocketStoriesCategories> =
|
|
|
|
|
|
|
|
mockk<FakeDataStore<SelectedPocketStoriesCategories>>(relaxed = true) as
|
|
|
|
|
|
|
|
DataStore<SelectedPocketStoriesCategories>
|
|
|
|
val pocketMiddleware = PocketUpdatesMiddleware(TestCoroutineScope(), mockk(), dataStore)
|
|
|
|
val pocketMiddleware = PocketUpdatesMiddleware(TestCoroutineScope(), mockk(), dataStore)
|
|
|
|
val homeStore = spyk(
|
|
|
|
val homeStore = spyk(
|
|
|
|
HomeFragmentStore(
|
|
|
|
HomeFragmentStore(
|
|
|
@ -117,10 +124,13 @@ class PocketUpdatesMiddlewareTest {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
@Test
|
|
|
|
|
|
|
|
@Suppress("UNCHECKED_CAST")
|
|
|
|
fun `WHEN DeselectPocketStoriesCategory is dispatched THEN persist details in DataStore`() {
|
|
|
|
fun `WHEN DeselectPocketStoriesCategory is dispatched THEN persist details in DataStore`() {
|
|
|
|
val categ1 = PocketRecommendedStoriesCategory("categ1")
|
|
|
|
val categ1 = PocketRecommendedStoriesCategory("categ1")
|
|
|
|
val categ2 = PocketRecommendedStoriesCategory("categ2")
|
|
|
|
val categ2 = PocketRecommendedStoriesCategory("categ2")
|
|
|
|
val dataStore: DataStore<SelectedPocketStoriesCategories> = mockk(relaxed = true)
|
|
|
|
val dataStore: DataStore<SelectedPocketStoriesCategories> =
|
|
|
|
|
|
|
|
mockk<FakeDataStore<SelectedPocketStoriesCategories>>(relaxed = true) as
|
|
|
|
|
|
|
|
DataStore<SelectedPocketStoriesCategories>
|
|
|
|
val pocketMiddleware = PocketUpdatesMiddleware(TestCoroutineScope(), mockk(), dataStore)
|
|
|
|
val pocketMiddleware = PocketUpdatesMiddleware(TestCoroutineScope(), mockk(), dataStore)
|
|
|
|
val homeStore = spyk(
|
|
|
|
val homeStore = spyk(
|
|
|
|
HomeFragmentStore(
|
|
|
|
HomeFragmentStore(
|
|
|
@ -138,8 +148,11 @@ class PocketUpdatesMiddlewareTest {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
@Test
|
|
|
|
|
|
|
|
@Suppress("UNCHECKED_CAST")
|
|
|
|
fun `WHEN persistCategories is called THEN update dataStore`() {
|
|
|
|
fun `WHEN persistCategories is called THEN update dataStore`() {
|
|
|
|
val dataStore: DataStore<SelectedPocketStoriesCategories> = mockk(relaxed = true)
|
|
|
|
val dataStore: DataStore<SelectedPocketStoriesCategories> =
|
|
|
|
|
|
|
|
mockk<FakeDataStore<SelectedPocketStoriesCategories>>(relaxed = true) as
|
|
|
|
|
|
|
|
DataStore<SelectedPocketStoriesCategories>
|
|
|
|
|
|
|
|
|
|
|
|
persistSelectedCategories(TestCoroutineScope(), listOf(mockk(relaxed = true)), dataStore)
|
|
|
|
persistSelectedCategories(TestCoroutineScope(), listOf(mockk(relaxed = true)), dataStore)
|
|
|
|
|
|
|
|
|
|
|
@ -148,6 +161,7 @@ class PocketUpdatesMiddlewareTest {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
@Test
|
|
|
|
|
|
|
|
@Suppress("UNCHECKED_CAST")
|
|
|
|
fun `WHEN restoreSelectedCategories is called THEN dispatch PocketStoriesCategoriesSelectionsChange with data read from the persistence layer`() {
|
|
|
|
fun `WHEN restoreSelectedCategories is called THEN dispatch PocketStoriesCategoriesSelectionsChange with data read from the persistence layer`() {
|
|
|
|
val persistedSelectedCategory: SelectedPocketStoriesCategory = mockk {
|
|
|
|
val persistedSelectedCategory: SelectedPocketStoriesCategory = mockk {
|
|
|
|
every { name } returns "testCategory"
|
|
|
|
every { name } returns "testCategory"
|
|
|
@ -156,9 +170,10 @@ class PocketUpdatesMiddlewareTest {
|
|
|
|
val persistedSelectedCategories: SelectedPocketStoriesCategories = mockk {
|
|
|
|
val persistedSelectedCategories: SelectedPocketStoriesCategories = mockk {
|
|
|
|
every { valuesList } returns mutableListOf(persistedSelectedCategory)
|
|
|
|
every { valuesList } returns mutableListOf(persistedSelectedCategory)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
val dataStore: DataStore<SelectedPocketStoriesCategories> = mockk {
|
|
|
|
val dataStore: DataStore<SelectedPocketStoriesCategories> =
|
|
|
|
every { data } returns flowOf(persistedSelectedCategories)
|
|
|
|
mockk<FakeDataStore<SelectedPocketStoriesCategories>>(relaxed = true) {
|
|
|
|
}
|
|
|
|
every { data } returns flowOf(persistedSelectedCategories)
|
|
|
|
|
|
|
|
} as DataStore<SelectedPocketStoriesCategories>
|
|
|
|
val currentCategories = listOf(mockk<PocketRecommendedStoriesCategory>())
|
|
|
|
val currentCategories = listOf(mockk<PocketRecommendedStoriesCategory>())
|
|
|
|
val homeStore = spyk(
|
|
|
|
val homeStore = spyk(
|
|
|
|
HomeFragmentStore(HomeFragmentState())
|
|
|
|
HomeFragmentStore(HomeFragmentState())
|
|
|
@ -183,3 +198,18 @@ class PocketUpdatesMiddlewareTest {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Incomplete fake of a [DataStore].
|
|
|
|
|
|
|
|
* Respects the [DataStore] contract with basic method implementations but needs to have mocked behavior
|
|
|
|
|
|
|
|
* for more complex interactions.
|
|
|
|
|
|
|
|
* Can be used as a replacement for mocks of the [DataStore] interface which might fail intermittently.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private class FakeDataStore<T> : DataStore<T?> {
|
|
|
|
|
|
|
|
override val data: Flow<T?>
|
|
|
|
|
|
|
|
get() = flow { }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override suspend fun updateData(transform: suspend (t: T?) -> T?): T? {
|
|
|
|
|
|
|
|
return transform(null)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|