mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-923 Collections | Empty states (#3013)
* DROID-923 no query fix * DROID-923 set, no objects * DROID-923 collection, no items * DROID-923 delete legacy param * DROID-923 check setOf for only valid objects * DROID-923 tests * DROID-923 update turbin library version
This commit is contained in:
parent
3041605feb
commit
73d4a1658f
10 changed files with 278 additions and 170 deletions
|
@ -442,7 +442,7 @@ open class ObjectSetFragment :
|
|||
addNewButton.isEnabled = true
|
||||
customizeViewButton.isEnabled = true
|
||||
viewerTitle.text = state.title
|
||||
dataViewInfo.show(type = DataViewInfo.TYPE.SET_NO_ITEMS, extra = state.type)
|
||||
dataViewInfo.show(type = DataViewInfo.TYPE.SET_NO_ITEMS)
|
||||
setViewer(viewer = null)
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ class DataViewInfo @JvmOverloads constructor(
|
|||
val binding = ViewDataviewInfoBinding.inflate(LayoutInflater.from(context), this, true)
|
||||
private var type: TYPE = TYPE.INIT
|
||||
|
||||
fun show(type: TYPE, extra: String = "") {
|
||||
fun show(type: TYPE) {
|
||||
this.type = type
|
||||
visible()
|
||||
when (type) {
|
||||
|
@ -46,7 +46,7 @@ class DataViewInfo @JvmOverloads constructor(
|
|||
TYPE.SET_NO_ITEMS -> {
|
||||
binding.title.text = resources.getString(R.string.set_no_items_title)
|
||||
binding.description.text =
|
||||
resources.getString(R.string.set_no_items_description, extra)
|
||||
resources.getString(R.string.set_no_items_description)
|
||||
binding.button.text = resources.getString(R.string.set_no_items_button)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -611,13 +611,13 @@
|
|||
|
||||
<string name="content_description_customize_view_button">Customize-view button</string>
|
||||
<string name="collection_no_items_title">No objects</string>
|
||||
<string name="collection_no_items_description">Add objects or turn into set to aggregate objects with\n equal types or relations</string>
|
||||
<string name="collection_no_items_description">Create first object to continue</string>
|
||||
<string name="collection_no_items_button">Create object</string>
|
||||
<string name="set_no_query_title">No query selected</string>
|
||||
<string name="set_no_query_description">All objects satisfying query will be displayed in Set</string>
|
||||
<string name="set_no_query_description">Add search query to aggregate objects with equal types and relations in a live mode</string>
|
||||
<string name="set_no_query_button">Select query</string>
|
||||
<string name="set_no_items_title">No objects</string>
|
||||
<string name="set_no_items_description">No objects of type \"%1$s\" found in your account, please create the first object</string>
|
||||
<string name="set_no_items_description">Create first object to continue</string>
|
||||
<string name="set_no_items_button">Create object</string>
|
||||
<string name="set_collection_view_not_present">View is not present in set or collection, please recreate object</string>
|
||||
<string name="menu_turn_to_collection">Turn into collection</string>
|
||||
|
|
|
@ -47,7 +47,7 @@ katexVersion = '1.0.2'
|
|||
robolectricLatestVersion = '4.7.3'
|
||||
kluentVersion = '1.14'
|
||||
timberJunitVersion = '1.0.1'
|
||||
turbineVersion = '0.7.0'
|
||||
turbineVersion = '0.12.1'
|
||||
coroutineTestingVersion = '1.6.4'
|
||||
liveDataTestingVersion = '1.2.0'
|
||||
espressoVersion = '3.4.0'
|
||||
|
|
|
@ -13,7 +13,7 @@ sealed class DataViewViewState {
|
|||
sealed class Set : DataViewViewState() {
|
||||
object NoQuery : Set()
|
||||
object NoView : Set()
|
||||
data class NoItems(val title: String, val type: String) : Set()
|
||||
data class NoItems(val title: String) : Set()
|
||||
data class Default(val viewer: Viewer?) : Set()
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ import com.anytypeio.anytype.presentation.objects.getProperName
|
|||
import com.anytypeio.anytype.presentation.relations.ObjectRelationView
|
||||
import com.anytypeio.anytype.presentation.relations.ObjectSetConfig.ID_KEY
|
||||
import com.anytypeio.anytype.presentation.relations.isSystemKey
|
||||
import com.anytypeio.anytype.presentation.relations.objectTypeRelation
|
||||
import com.anytypeio.anytype.presentation.relations.view
|
||||
import com.anytypeio.anytype.presentation.sets.model.ObjectView
|
||||
import com.anytypeio.anytype.presentation.sets.model.SimpleRelationView
|
||||
|
@ -317,10 +316,20 @@ fun List<DVViewerRelation>.updateViewerRelations(updates: List<DVViewerRelationU
|
|||
return relations
|
||||
}
|
||||
|
||||
fun ObjectState.DataView.Set.getSetOf(ctx: Id): List<Id> {
|
||||
fun ObjectState.DataView.Set.getSetOfValue(ctx: Id): List<Id> {
|
||||
return ObjectWrapper.Basic(details[ctx]?.map.orEmpty()).setOf
|
||||
}
|
||||
|
||||
fun ObjectState.DataView.filterOutDeletedAndMissingObjects(query: List<Id>): List<Id> {
|
||||
return query.filter(::isValidObject)
|
||||
}
|
||||
|
||||
private fun ObjectState.DataView.isValidObject(objectId: Id): Boolean {
|
||||
val objectDetails = details[objectId] ?: return false
|
||||
val objectWrapper = ObjectWrapper.Basic(objectDetails.map)
|
||||
return objectWrapper.isDeleted != true
|
||||
}
|
||||
|
||||
fun DVViewer.updateFields(fields: DVViewerFields?): DVViewer {
|
||||
if (fields == null) return this
|
||||
return copy(
|
||||
|
|
|
@ -426,7 +426,8 @@ class ObjectSetViewModel(
|
|||
state.dataViewContent.relationLinks.mapNotNull {
|
||||
storeOfRelations.getByKey(it.key)
|
||||
}
|
||||
val setOf = state.getSetOf(ctx = context)
|
||||
val setOfValue = state.getSetOfValue(ctx = context)
|
||||
val query = state.filterOutDeletedAndMissingObjects(query = setOfValue)
|
||||
val render = state.viewerById(currentViewId)
|
||||
?.render(
|
||||
coverImageHashProvider = coverImageHashProvider,
|
||||
|
@ -437,13 +438,11 @@ class ObjectSetViewModel(
|
|||
store = objectStore
|
||||
)
|
||||
when {
|
||||
setOf.isEmpty() -> DataViewViewState.Set.NoQuery
|
||||
query.isEmpty() -> DataViewViewState.Set.NoQuery
|
||||
setOfValue.isEmpty() -> DataViewViewState.Set.NoQuery
|
||||
render == null -> DataViewViewState.Set.NoView
|
||||
render.isEmpty() -> {
|
||||
DataViewViewState.Set.NoItems(
|
||||
title = render.title,
|
||||
type = state.details[setOf[0]]?.name.orEmpty()
|
||||
)
|
||||
DataViewViewState.Set.NoItems(title = render.title)
|
||||
}
|
||||
else -> DataViewViewState.Set.Default(viewer = render)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@ import com.anytypeio.anytype.domain.search.DataViewSubscriptionContainer
|
|||
import com.anytypeio.anytype.presentation.relations.ObjectSetConfig
|
||||
import com.anytypeio.anytype.presentation.search.ObjectSearchConstants
|
||||
import com.anytypeio.anytype.presentation.sets.ObjectSetSession
|
||||
import com.anytypeio.anytype.presentation.sets.getSetOf
|
||||
import com.anytypeio.anytype.presentation.sets.filterOutDeletedAndMissingObjects
|
||||
import com.anytypeio.anytype.presentation.sets.getSetOfValue
|
||||
import com.anytypeio.anytype.presentation.sets.state.ObjectState
|
||||
import com.anytypeio.anytype.presentation.sets.updateFormatForSubscription
|
||||
import com.anytypeio.anytype.presentation.sets.viewerById
|
||||
|
@ -96,11 +97,22 @@ class DefaultDataViewSubscription(private val dataViewSubscriptionContainer: Dat
|
|||
Timber.w("Data view set subscription: active viewer is null")
|
||||
return emptyFlow()
|
||||
}
|
||||
val source = state.getSetOf(ctx = context)
|
||||
if (source.isEmpty()) {
|
||||
Timber.w("Data view set subscription: source is empty")
|
||||
|
||||
val setOfValue = state.getSetOfValue(ctx = context)
|
||||
if (setOfValue.isEmpty()) {
|
||||
Timber.w("Data view set subscription: setOf value is empty, proceed without subscription")
|
||||
return emptyFlow()
|
||||
}
|
||||
|
||||
val query = state.filterOutDeletedAndMissingObjects(setOfValue)
|
||||
if (query.isEmpty()) {
|
||||
Timber.w(
|
||||
"Data view set subscription: query has no valid types or relations, " +
|
||||
"proceed without subscription"
|
||||
)
|
||||
return emptyFlow()
|
||||
}
|
||||
|
||||
val filters =
|
||||
activeViewer.filters.updateFormatForSubscription(storeOfRelations) + ObjectSearchConstants.defaultDataViewFilters(
|
||||
workspaceId = workspaceId
|
||||
|
@ -112,7 +124,7 @@ class DefaultDataViewSubscription(private val dataViewSubscriptionContainer: Dat
|
|||
subscription = getSubscriptionId(context),
|
||||
sorts = activeViewer.sorts,
|
||||
filters = filters,
|
||||
sources = source,
|
||||
sources = query,
|
||||
keys = keys,
|
||||
limit = ObjectSetConfig.DEFAULT_LIMIT,
|
||||
offset = offset
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.anytypeio.anytype.presentation.collections
|
||||
|
||||
import app.cash.turbine.test
|
||||
import app.cash.turbine.testIn
|
||||
import com.anytypeio.anytype.presentation.sets.DataViewViewState
|
||||
import com.anytypeio.anytype.presentation.sets.ObjectSetViewModel
|
||||
import com.anytypeio.anytype.presentation.sets.main.ObjectSetViewModelTestSetup
|
||||
|
@ -49,35 +49,21 @@ class ObjectStateCollectionViewTest : ObjectSetViewModelTestSetup() {
|
|||
// TESTING
|
||||
viewModel.onStart(ctx = root)
|
||||
|
||||
// ASSERT COLLECTION OBJECT STATE
|
||||
stateReducer.state.test {
|
||||
val first = awaitItem()
|
||||
assertIs<ObjectState.Init>(first)
|
||||
val headerFlow = viewModel.header.testIn(backgroundScope)
|
||||
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
|
||||
val stateFlow = stateReducer.state.testIn(backgroundScope)
|
||||
|
||||
val second = awaitItem()
|
||||
assertIs<ObjectState.DataView.Collection>(second)
|
||||
assertNull(headerFlow.awaitItem())
|
||||
assertIs<ObjectState.Init>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
|
||||
|
||||
}
|
||||
assertIs<ObjectState.DataView.Collection>(stateFlow.awaitItem())
|
||||
|
||||
// ASSERT HEADER STATE
|
||||
viewModel.header.test {
|
||||
val first = awaitItem()
|
||||
assertNull(first)
|
||||
|
||||
val second = awaitItem()
|
||||
assertEquals(
|
||||
expected = mockObjectCollection.title.content.asText().text,
|
||||
actual = second?.text
|
||||
)
|
||||
expectNoEvents()
|
||||
}
|
||||
|
||||
// ASSERT DATA VIEW STATE
|
||||
viewModel.currentViewer.test {
|
||||
val first = awaitItem()
|
||||
assertIs<DataViewViewState.Init>(first)
|
||||
expectNoEvents()
|
||||
}
|
||||
assertEquals(
|
||||
expected = mockObjectCollection.title.content.asText().text,
|
||||
actual = headerFlow.awaitItem()?.text
|
||||
)
|
||||
viewerFlow.expectNoEvents()
|
||||
|
||||
// ASSERT NO SUBSCRIPTION TO COLLECTION RECORDS
|
||||
advanceUntilIdle()
|
||||
|
@ -102,27 +88,16 @@ class ObjectStateCollectionViewTest : ObjectSetViewModelTestSetup() {
|
|||
// TESTING
|
||||
viewModel.onStart(ctx = root)
|
||||
|
||||
// ASSERT COLLECTION OBJECT STATE
|
||||
stateReducer.state.test {
|
||||
val first = awaitItem()
|
||||
assertIs<ObjectState.Init>(first)
|
||||
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
|
||||
val stateFlow = stateReducer.state.testIn(backgroundScope)
|
||||
|
||||
val second = awaitItem()
|
||||
assertIs<ObjectState.DataView.Collection>(second)
|
||||
expectNoEvents()
|
||||
}
|
||||
assertIs<ObjectState.Init>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
|
||||
|
||||
// ASSERT DATA VIEW STATE
|
||||
viewModel.currentViewer.test {
|
||||
val first = awaitItem()
|
||||
assertIs<DataViewViewState.Init>(first)
|
||||
assertIs<ObjectState.DataView.Collection>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Collection.NoView>(viewerFlow.awaitItem())
|
||||
|
||||
val second = awaitItem()
|
||||
assertIs<DataViewViewState.Collection.NoView>(second)
|
||||
expectNoEvents()
|
||||
}
|
||||
|
||||
// ASSERT SUBSCRIPTION TO COLLECTION RECORDS
|
||||
// ASSERT NO SUBSCRIPTION TO COLLECTION RECORDS
|
||||
advanceUntilIdle()
|
||||
verifyNoInteractions(repo)
|
||||
}
|
||||
|
@ -154,25 +129,15 @@ class ObjectStateCollectionViewTest : ObjectSetViewModelTestSetup() {
|
|||
// TESTING
|
||||
viewModel.onStart(ctx = root)
|
||||
|
||||
// ASSERT COLLECTION OBJECT STATE
|
||||
stateReducer.state.test {
|
||||
val first = awaitItem()
|
||||
assertIs<ObjectState.Init>(first)
|
||||
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
|
||||
val stateFlow = stateReducer.state.testIn(backgroundScope)
|
||||
|
||||
val second = awaitItem()
|
||||
assertIs<ObjectState.DataView.Collection>(second)
|
||||
expectNoEvents()
|
||||
}
|
||||
// ASSERT STATES
|
||||
assertIs<ObjectState.Init>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
|
||||
|
||||
// ASSERT DATA VIEW STATE
|
||||
viewModel.currentViewer.test {
|
||||
val first = awaitItem()
|
||||
assertIs<DataViewViewState.Init>(first)
|
||||
|
||||
val second = awaitItem()
|
||||
assertIs<DataViewViewState.Collection.NoItems>(second)
|
||||
expectNoEvents()
|
||||
}
|
||||
assertIs<ObjectState.DataView.Collection>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Collection.NoItems>(viewerFlow.awaitItem())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -203,27 +168,15 @@ class ObjectStateCollectionViewTest : ObjectSetViewModelTestSetup() {
|
|||
// TESTING
|
||||
viewModel.onStart(ctx = root)
|
||||
|
||||
// ASSERT COLLECTION OBJECT STATE
|
||||
stateReducer.state.test {
|
||||
val first = awaitItem()
|
||||
assertIs<ObjectState.Init>(first)
|
||||
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
|
||||
val stateFlow = stateReducer.state.testIn(backgroundScope)
|
||||
|
||||
val second = awaitItem()
|
||||
assertIs<ObjectState.DataView.Collection>(second)
|
||||
expectNoEvents()
|
||||
}
|
||||
// ASSERT STATES
|
||||
assertIs<ObjectState.Init>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
|
||||
|
||||
// ASSERT DATA VIEW STATE
|
||||
viewModel.currentViewer.test {
|
||||
val first = awaitItem()
|
||||
assertIs<DataViewViewState.Init>(first)
|
||||
|
||||
val second = awaitItem()
|
||||
assertIs<DataViewViewState.Collection.NoItems>(second)
|
||||
|
||||
val third = awaitItem()
|
||||
assertIs<DataViewViewState.Collection.Default>(third)
|
||||
expectNoEvents()
|
||||
}
|
||||
assertIs<ObjectState.DataView.Collection>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Collection.NoItems>(viewerFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Collection.Default>(viewerFlow.awaitItem())
|
||||
}
|
||||
}
|
|
@ -1,9 +1,14 @@
|
|||
package com.anytypeio.anytype.presentation.collections
|
||||
|
||||
import app.cash.turbine.test
|
||||
import app.cash.turbine.testIn
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.ObjectTypeIds
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.presentation.relations.ObjectSetConfig
|
||||
import com.anytypeio.anytype.presentation.search.ObjectSearchConstants
|
||||
import com.anytypeio.anytype.presentation.sets.DataViewViewState
|
||||
import com.anytypeio.anytype.presentation.sets.ObjectSetViewModel
|
||||
import com.anytypeio.anytype.presentation.sets.main.ObjectSetViewModelTestSetup
|
||||
|
@ -11,11 +16,16 @@ import com.anytypeio.anytype.presentation.sets.state.ObjectState
|
|||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertIs
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.advanceUntilIdle
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import net.bytebuddy.utility.RandomString
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.kotlin.eq
|
||||
import org.mockito.kotlin.times
|
||||
import org.mockito.kotlin.verifyBlocking
|
||||
import org.mockito.kotlin.verifyNoInteractions
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
|
@ -131,26 +141,19 @@ class ObjectStateSetViewTest : ObjectSetViewModelTestSetup() {
|
|||
// TESTING
|
||||
viewModel.onStart(ctx = root)
|
||||
|
||||
// ASSERT SET OBJECT STATE
|
||||
stateReducer.state.test {
|
||||
val first = awaitItem()
|
||||
assertIs<ObjectState.Init>(first)
|
||||
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
|
||||
val stateFlow = stateReducer.state.testIn(backgroundScope)
|
||||
|
||||
val second = awaitItem()
|
||||
assertIs<ObjectState.DataView.Set>(second)
|
||||
}
|
||||
// ASSERT STATES
|
||||
assertIs<ObjectState.Init>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
|
||||
|
||||
assertIs<ObjectState.DataView.Set>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Set.NoQuery>(viewerFlow.awaitItem())
|
||||
|
||||
// ASSERT SUBSCRIPTION TO SET RECORDS
|
||||
advanceUntilIdle()
|
||||
verifyNoInteractions(repo)
|
||||
|
||||
// ASSERT DATA VIEW STATE
|
||||
viewModel.currentViewer.test {
|
||||
val first = awaitItem()
|
||||
assertIs<DataViewViewState.Init>(first)
|
||||
|
||||
val second = awaitItem()
|
||||
assertIs<DataViewViewState.Set.NoQuery>(second)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -167,28 +170,15 @@ class ObjectStateSetViewTest : ObjectSetViewModelTestSetup() {
|
|||
// TESTING
|
||||
viewModel.onStart(ctx = root)
|
||||
|
||||
// ASSERT SET OBJECT STATE
|
||||
stateReducer.state.test {
|
||||
val first = awaitItem()
|
||||
assertIs<ObjectState.Init>(first)
|
||||
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
|
||||
val stateFlow = stateReducer.state.testIn(backgroundScope)
|
||||
|
||||
val second = awaitItem()
|
||||
assertIs<ObjectState.DataView.Set>(second)
|
||||
}
|
||||
// ASSERT STATES
|
||||
assertIs<ObjectState.Init>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
|
||||
|
||||
// ASSERT SUBSCRIPTION TO SET RECORDS
|
||||
verifyNoInteractions(repo)
|
||||
|
||||
// ASSERT DATA VIEW STATE
|
||||
viewModel.currentViewer.test {
|
||||
val first = awaitItem()
|
||||
assertIs<DataViewViewState.Init>(first)
|
||||
|
||||
val second = awaitItem()
|
||||
assertIs<DataViewViewState.Set.NoView>(second)
|
||||
|
||||
expectNoEvents()
|
||||
}
|
||||
assertIs<ObjectState.DataView.Set>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Set.NoView>(viewerFlow.awaitItem())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -214,26 +204,16 @@ class ObjectStateSetViewTest : ObjectSetViewModelTestSetup() {
|
|||
// TESTING
|
||||
viewModel.onStart(ctx = root)
|
||||
|
||||
// ASSERT SET OBJECT STATE
|
||||
stateReducer.state.test {
|
||||
val first = awaitItem()
|
||||
assertIs<ObjectState.Init>(first)
|
||||
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
|
||||
val stateFlow = stateReducer.state.testIn(backgroundScope)
|
||||
|
||||
val second = awaitItem()
|
||||
assertIs<ObjectState.DataView.Set>(second)
|
||||
}
|
||||
// ASSERT STATES
|
||||
assertIs<ObjectState.Init>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
|
||||
|
||||
// ASSERT DATA VIEW STATE
|
||||
viewModel.currentViewer.test {
|
||||
val first = awaitItem()
|
||||
assertIs<DataViewViewState.Init>(first)
|
||||
|
||||
val second = awaitItem()
|
||||
assertIs<DataViewViewState.Set.NoItems>(second)
|
||||
|
||||
val third = awaitItem()
|
||||
assertIs<DataViewViewState.Set.Default>(third)
|
||||
}
|
||||
assertIs<ObjectState.DataView.Set>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Set.NoItems>(viewerFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Set.Default>(viewerFlow.awaitItem())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -257,22 +237,177 @@ class ObjectStateSetViewTest : ObjectSetViewModelTestSetup() {
|
|||
// TESTING
|
||||
viewModel.onStart(ctx = root)
|
||||
|
||||
// ASSERT SET OBJECT STATE
|
||||
stateReducer.state.test {
|
||||
val first = awaitItem()
|
||||
assertIs<ObjectState.Init>(first)
|
||||
// ASSERT STATES
|
||||
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
|
||||
val stateFlow = stateReducer.state.testIn(backgroundScope)
|
||||
|
||||
val second = awaitItem()
|
||||
assertIs<ObjectState.DataView.Set>(second)
|
||||
}
|
||||
// ASSERT STATES
|
||||
assertIs<ObjectState.Init>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
|
||||
|
||||
// ASSERT DATA VIEW STATE
|
||||
viewModel.currentViewer.test {
|
||||
val first = awaitItem()
|
||||
assertIs<DataViewViewState.Init>(first)
|
||||
assertIs<ObjectState.DataView.Set>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Set.NoItems>(viewerFlow.awaitItem())
|
||||
}
|
||||
|
||||
val second = awaitItem()
|
||||
assertIs<DataViewViewState.Set.NoItems>(second)
|
||||
@Test
|
||||
fun `Displaying Object Sets with Non-Deleted Types Only`() = runTest {
|
||||
// SETUP
|
||||
stubWorkspaceManager(mockObjectSet.workspaceId)
|
||||
stubInterceptEvents()
|
||||
stubInterceptThreadStatus()
|
||||
|
||||
val typeDeleted1 = ObjectWrapper.Type(
|
||||
mapOf(
|
||||
Relations.ID to RandomString.make(),
|
||||
Relations.IS_DELETED to true
|
||||
)
|
||||
)
|
||||
val type2 = ObjectWrapper.Type(
|
||||
mapOf(
|
||||
Relations.ID to RandomString.make(),
|
||||
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE
|
||||
)
|
||||
)
|
||||
val typeDeleted3 = ObjectWrapper.Type(
|
||||
mapOf(
|
||||
Relations.ID to RandomString.make(),
|
||||
)
|
||||
)
|
||||
|
||||
val detailsDeletedSetOf = Block.Details(
|
||||
details = mapOf(
|
||||
root to Block.Fields(
|
||||
mapOf(
|
||||
Relations.ID to root,
|
||||
Relations.LAYOUT to ObjectType.Layout.SET.code.toDouble(),
|
||||
Relations.SET_OF to listOf(typeDeleted1.id, type2.id, typeDeleted3.id)
|
||||
)
|
||||
),
|
||||
typeDeleted1.id to Block.Fields(
|
||||
mapOf(
|
||||
Relations.ID to typeDeleted1.id,
|
||||
Relations.IS_DELETED to true
|
||||
)
|
||||
),
|
||||
type2.id to Block.Fields(
|
||||
mapOf(
|
||||
Relations.ID to type2.id,
|
||||
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
stubOpenObject(
|
||||
doc = listOf(mockObjectSet.header, mockObjectSet.title, mockObjectSet.dataView),
|
||||
details = detailsDeletedSetOf
|
||||
)
|
||||
stubSubscriptionResults(
|
||||
subscription = mockObjectSet.subscriptionId,
|
||||
workspace = mockObjectSet.workspaceId,
|
||||
storeOfRelations = storeOfRelations,
|
||||
keys = mockObjectSet.dvKeys,
|
||||
sources = listOf(type2.id),
|
||||
objects = listOf(mockObjectSet.obj1, mockObjectSet.obj2),
|
||||
dvFilters = mockObjectSet.filters
|
||||
)
|
||||
|
||||
// TESTING
|
||||
viewModel.onStart(ctx = root)
|
||||
|
||||
// ASSERT STATES
|
||||
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
|
||||
val stateFlow = stateReducer.state.testIn(backgroundScope)
|
||||
|
||||
assertIs<ObjectState.Init>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
|
||||
|
||||
assertIs<ObjectState.DataView.Set>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Set.NoItems>(viewerFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Set.Default>(viewerFlow.awaitItem())
|
||||
|
||||
stateFlow.ensureAllEventsConsumed()
|
||||
viewerFlow.ensureAllEventsConsumed()
|
||||
|
||||
advanceUntilIdle()
|
||||
verifyBlocking(repo, times(1)) {
|
||||
searchObjectsWithSubscription(
|
||||
eq(mockObjectSet.subscriptionId),
|
||||
eq(listOf()),
|
||||
eq(
|
||||
mockObjectSet.filters + ObjectSearchConstants.defaultDataViewFilters(
|
||||
mockObjectSet.workspaceId
|
||||
)
|
||||
),
|
||||
eq(ObjectSearchConstants.defaultDataViewKeys + mockObjectSet.dvKeys),
|
||||
eq(listOf(type2.id)),
|
||||
eq(0L),
|
||||
eq(ObjectSetConfig.DEFAULT_LIMIT),
|
||||
eq(null),
|
||||
eq(null),
|
||||
eq(null),
|
||||
eq(null),
|
||||
eq(null)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Displaying Object Set with No Query State When All Types are Deleted`() = runTest {
|
||||
// SETUP
|
||||
stubWorkspaceManager(mockObjectSet.workspaceId)
|
||||
stubInterceptEvents()
|
||||
stubInterceptThreadStatus()
|
||||
|
||||
val typeDeleted1 = ObjectWrapper.Type(
|
||||
mapOf(
|
||||
Relations.ID to RandomString.make(),
|
||||
Relations.IS_DELETED to true
|
||||
)
|
||||
)
|
||||
val typeDeleted3 = ObjectWrapper.Type(
|
||||
mapOf(
|
||||
Relations.ID to RandomString.make(),
|
||||
)
|
||||
)
|
||||
|
||||
val detailsDeletedSetOf = Block.Details(
|
||||
details = mapOf(
|
||||
root to Block.Fields(
|
||||
mapOf(
|
||||
Relations.ID to root,
|
||||
Relations.LAYOUT to ObjectType.Layout.SET.code.toDouble(),
|
||||
Relations.SET_OF to listOf(typeDeleted1.id, typeDeleted3.id)
|
||||
)
|
||||
),
|
||||
typeDeleted1.id to Block.Fields(
|
||||
mapOf(
|
||||
Relations.ID to typeDeleted1.id,
|
||||
Relations.IS_DELETED to true
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
stubOpenObject(
|
||||
doc = listOf(mockObjectSet.header, mockObjectSet.title, mockObjectSet.dataView),
|
||||
details = detailsDeletedSetOf
|
||||
)
|
||||
|
||||
// TESTING
|
||||
viewModel.onStart(ctx = root)
|
||||
|
||||
// ASSERT STATES
|
||||
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
|
||||
val stateFlow = stateReducer.state.testIn(backgroundScope)
|
||||
|
||||
assertIs<ObjectState.Init>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
|
||||
|
||||
assertIs<ObjectState.DataView.Set>(stateFlow.awaitItem())
|
||||
assertIs<DataViewViewState.Set.NoQuery>(viewerFlow.awaitItem())
|
||||
|
||||
stateFlow.ensureAllEventsConsumed()
|
||||
viewerFlow.ensureAllEventsConsumed()
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue