mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-579 Sets | Enhancement | Empty state for sets without selected source (#2688)
This commit is contained in:
parent
fb4c7ded1c
commit
d77abac129
4 changed files with 336 additions and 310 deletions
|
@ -793,7 +793,14 @@ open class ObjectSetFragment :
|
|||
jobs += lifecycleScope.subscribe(vm.commands) { observeCommands(it) }
|
||||
jobs += lifecycleScope.subscribe(vm.header.filterNotNull()) { bindHeader(it) }
|
||||
jobs += lifecycleScope.subscribe(vm.currentViewer) { setupViewer(it) }
|
||||
jobs += lifecycleScope.subscribe(vm.error) { binding.tvError.text = it }
|
||||
jobs += lifecycleScope.subscribe(vm.error) { err ->
|
||||
if (err.isNullOrEmpty())
|
||||
binding.tvError.gone()
|
||||
else {
|
||||
binding.tvError.text = err
|
||||
binding.tvError.visible()
|
||||
}
|
||||
}
|
||||
jobs += lifecycleScope.subscribe(vm.pagination) { (index, count) ->
|
||||
binding.paginatorToolbar.set(count = count, index = index)
|
||||
if (count > 1) {
|
||||
|
|
|
@ -122,6 +122,7 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/gridContainer"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<include
|
||||
|
|
|
@ -159,7 +159,7 @@ class ObjectSetViewModel(
|
|||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
reducer.state.filter { it.isInitialized }.collect { set ->
|
||||
reducer.state.collect { set ->
|
||||
Timber.d("FLOW:: Updating header and tabs")
|
||||
featured.value = set.featuredRelations(
|
||||
ctx = context,
|
||||
|
@ -173,11 +173,13 @@ class ObjectSetViewModel(
|
|||
title = it
|
||||
)
|
||||
}
|
||||
if (set.viewers.isEmpty()) {
|
||||
error.value = DATA_VIEW_HAS_NO_VIEW_MSG
|
||||
_viewerTabs.value = emptyList()
|
||||
} else {
|
||||
_viewerTabs.value = set.tabs(session.currentViewerId.value)
|
||||
if (set.isInitialized) {
|
||||
if (set.viewers.isEmpty()) {
|
||||
error.value = DATA_VIEW_HAS_NO_VIEW_MSG
|
||||
_viewerTabs.value = emptyList()
|
||||
} else {
|
||||
_viewerTabs.value = set.tabs(session.currentViewerId.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -517,8 +519,24 @@ class ObjectSetViewModel(
|
|||
)
|
||||
}
|
||||
} else {
|
||||
// TODO Use loading state to prevent user from editing title if set of objects is not ready.
|
||||
Timber.e("Skipping dispatching title update, because set of objects was not ready.")
|
||||
if (context.isNotEmpty()) {
|
||||
viewModelScope.launch {
|
||||
setObjectDetails(
|
||||
UpdateDetail.Params(
|
||||
ctx = context,
|
||||
key = Relations.NAME,
|
||||
value = txt
|
||||
)
|
||||
).process(
|
||||
success = { dispatcher.send(it) },
|
||||
failure = {
|
||||
Timber.e(it, "Error while updating object set name")
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Timber.e("Skipping dispatching title update, because set of objects was not ready.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import com.anytypeio.anytype.core_models.Block
|
|||
import com.anytypeio.anytype.core_models.DV
|
||||
import com.anytypeio.anytype.core_models.DVViewer
|
||||
import com.anytypeio.anytype.core_models.DVViewerRelation
|
||||
import com.anytypeio.anytype.core_models.Event
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.Relation
|
||||
|
@ -18,6 +17,7 @@ import com.anytypeio.anytype.domain.page.CloseBlock
|
|||
import com.anytypeio.anytype.presentation.navigation.AppNavigation
|
||||
import com.anytypeio.anytype.presentation.objects.SupportedLayouts
|
||||
import com.anytypeio.anytype.presentation.relations.ObjectSetConfig
|
||||
import com.anytypeio.anytype.presentation.search.ObjectSearchConstants
|
||||
import com.anytypeio.anytype.presentation.sets.ObjectSetCommand
|
||||
import com.anytypeio.anytype.presentation.sets.ObjectSetViewModel
|
||||
import com.anytypeio.anytype.presentation.sets.model.Viewer
|
||||
|
@ -25,14 +25,11 @@ import com.anytypeio.anytype.presentation.util.CoroutinesTestRule
|
|||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
import com.anytypeio.anytype.test_utils.ValueClassAnswer
|
||||
import com.jraska.livedata.test
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.kotlin.doAnswer
|
||||
import org.mockito.kotlin.stub
|
||||
|
@ -139,7 +136,7 @@ class ObjectSetNavigationTest : ObjectSetViewModelTestSetup() {
|
|||
afterId = null,
|
||||
beforeId = null,
|
||||
sources = dv.content<DV>().sources,
|
||||
keys = dv.content<DV>().relations.map { it.key },
|
||||
keys = ObjectSearchConstants.defaultKeys + dv.content<DV>().relations.map { it.key },
|
||||
limit = ObjectSetConfig.DEFAULT_LIMIT,
|
||||
offset = 0,
|
||||
result = SearchResult(
|
||||
|
@ -210,124 +207,125 @@ class ObjectSetNavigationTest : ObjectSetViewModelTestSetup() {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `should emit navigation command for opening an object contained in given relation if this relation is read-only and object's layout is supported`() = runTest {
|
||||
fun `should emit navigation command for opening an object contained in given relation if this relation is read-only and object's layout is supported`() =
|
||||
runTest {
|
||||
|
||||
// SETUP
|
||||
// SETUP
|
||||
|
||||
val supportedObjectLayouts = listOf(
|
||||
ObjectType.Layout.BASIC,
|
||||
ObjectType.Layout.PROFILE,
|
||||
ObjectType.Layout.TODO,
|
||||
ObjectType.Layout.IMAGE,
|
||||
ObjectType.Layout.FILE
|
||||
)
|
||||
|
||||
val linkedProjectTargetId = "Linked project ID"
|
||||
val firstRecordId = "First record ID"
|
||||
|
||||
val record = mapOf(
|
||||
Relations.ID to firstRecordId,
|
||||
linkedProjectRelation.key to linkedProjectTargetId
|
||||
)
|
||||
|
||||
val obj = ObjectWrapper.Basic(record)
|
||||
val linkedObject = ObjectWrapper.Basic(
|
||||
mapOf(
|
||||
Relations.ID to linkedProjectTargetId,
|
||||
Relations.NAME to MockDataFactory.randomString(),
|
||||
Relations.LAYOUT to ObjectType.Layout.BASIC
|
||||
val supportedObjectLayouts = listOf(
|
||||
ObjectType.Layout.BASIC,
|
||||
ObjectType.Layout.PROFILE,
|
||||
ObjectType.Layout.TODO,
|
||||
ObjectType.Layout.IMAGE,
|
||||
ObjectType.Layout.FILE
|
||||
)
|
||||
)
|
||||
|
||||
val details = Block.Details(
|
||||
details = mapOf(
|
||||
linkedProjectTargetId to Block.Fields(
|
||||
mapOf(
|
||||
Relations.ID to linkedProjectTargetId,
|
||||
Relations.LAYOUT to supportedObjectLayouts.random().code.toDouble()
|
||||
)
|
||||
val linkedProjectTargetId = "Linked project ID"
|
||||
val firstRecordId = "First record ID"
|
||||
|
||||
val record = mapOf(
|
||||
Relations.ID to firstRecordId,
|
||||
linkedProjectRelation.key to linkedProjectTargetId
|
||||
)
|
||||
|
||||
val obj = ObjectWrapper.Basic(record)
|
||||
val linkedObject = ObjectWrapper.Basic(
|
||||
mapOf(
|
||||
Relations.ID to linkedProjectTargetId,
|
||||
Relations.NAME to MockDataFactory.randomString(),
|
||||
Relations.LAYOUT to ObjectType.Layout.BASIC
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
stubInterceptEvents()
|
||||
stubInterceptThreadStatus()
|
||||
stubCloseBlock()
|
||||
stubSubscriptionEventChannel()
|
||||
stubSearchWithSubscription(
|
||||
subscription = root,
|
||||
filters = dv.content<DV>().viewers.first().filters,
|
||||
sorts = dv.content<DV>().viewers.first().sorts,
|
||||
afterId = null,
|
||||
beforeId = null,
|
||||
sources = dv.content<DV>().sources,
|
||||
keys = dv.content<DV>().relations.map { it.key },
|
||||
limit = ObjectSetConfig.DEFAULT_LIMIT,
|
||||
offset = 0,
|
||||
result = SearchResult(
|
||||
results = listOf(obj),
|
||||
dependencies = listOf(linkedObject),
|
||||
counter = SearchResult.Counter(
|
||||
total = 1,
|
||||
prev = 0,
|
||||
next = 0
|
||||
)
|
||||
)
|
||||
)
|
||||
stubOpenObjectSet(
|
||||
doc = listOf(
|
||||
header,
|
||||
title,
|
||||
dv.copy(
|
||||
content = dv.content<DV>().copy(
|
||||
relations = listOf(
|
||||
linkedProjectRelation.copy(
|
||||
isReadOnly = true
|
||||
)
|
||||
val details = Block.Details(
|
||||
details = mapOf(
|
||||
linkedProjectTargetId to Block.Fields(
|
||||
mapOf(
|
||||
Relations.ID to linkedProjectTargetId,
|
||||
Relations.LAYOUT to supportedObjectLayouts.random().code.toDouble()
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
dataViewRestrictions = emptyList(),
|
||||
details = details
|
||||
)
|
||||
|
||||
val vm = givenViewModel()
|
||||
|
||||
vm.onStart(root)
|
||||
|
||||
// TESTING
|
||||
|
||||
vm.currentViewer.test {
|
||||
val stateBeforeLoaded = awaitItem()
|
||||
|
||||
assertIs<Viewer.GridView>(stateBeforeLoaded)
|
||||
|
||||
assertEquals(
|
||||
expected = 0,
|
||||
actual = stateBeforeLoaded.rows.size
|
||||
)
|
||||
|
||||
val stateAfterLoaded = awaitItem()
|
||||
|
||||
assertIs<Viewer.GridView>(stateAfterLoaded)
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = stateAfterLoaded.rows.size
|
||||
stubInterceptEvents()
|
||||
stubInterceptThreadStatus()
|
||||
stubCloseBlock()
|
||||
stubSubscriptionEventChannel()
|
||||
stubSearchWithSubscription(
|
||||
subscription = root,
|
||||
filters = dv.content<DV>().viewers.first().filters,
|
||||
sorts = dv.content<DV>().viewers.first().sorts,
|
||||
afterId = null,
|
||||
beforeId = null,
|
||||
sources = dv.content<DV>().sources,
|
||||
keys = ObjectSearchConstants.defaultKeys + dv.content<DV>().relations.map { it.key },
|
||||
limit = ObjectSetConfig.DEFAULT_LIMIT,
|
||||
offset = 0,
|
||||
result = SearchResult(
|
||||
results = listOf(obj),
|
||||
dependencies = listOf(linkedObject),
|
||||
counter = SearchResult.Counter(
|
||||
total = 1,
|
||||
prev = 0,
|
||||
next = 0
|
||||
)
|
||||
)
|
||||
)
|
||||
stubOpenObjectSet(
|
||||
doc = listOf(
|
||||
header,
|
||||
title,
|
||||
dv.copy(
|
||||
content = dv.content<DV>().copy(
|
||||
relations = listOf(
|
||||
linkedProjectRelation.copy(
|
||||
isReadOnly = true
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
dataViewRestrictions = emptyList(),
|
||||
details = details
|
||||
)
|
||||
|
||||
// Clicking on cell with linked projects.
|
||||
val testObserver = vm.navigation.test()
|
||||
val vm = givenViewModel()
|
||||
|
||||
vm.onGridCellClicked(stateAfterLoaded.rows.first().cells.last())
|
||||
vm.onStart(root)
|
||||
|
||||
testObserver.assertValue { value ->
|
||||
val content = value.peekContent()
|
||||
content == AppNavigation.Command.OpenObject(linkedProjectTargetId)
|
||||
// TESTING
|
||||
|
||||
vm.currentViewer.test {
|
||||
val stateBeforeLoaded = awaitItem()
|
||||
|
||||
assertIs<Viewer.GridView>(stateBeforeLoaded)
|
||||
|
||||
assertEquals(
|
||||
expected = 0,
|
||||
actual = stateBeforeLoaded.rows.size
|
||||
)
|
||||
|
||||
val stateAfterLoaded = awaitItem()
|
||||
|
||||
assertIs<Viewer.GridView>(stateAfterLoaded)
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = stateAfterLoaded.rows.size
|
||||
)
|
||||
|
||||
// Clicking on cell with linked projects.
|
||||
val testObserver = vm.navigation.test()
|
||||
|
||||
vm.onGridCellClicked(stateAfterLoaded.rows.first().cells.last())
|
||||
|
||||
testObserver.assertValue { value ->
|
||||
val content = value.peekContent()
|
||||
content == AppNavigation.Command.OpenObject(linkedProjectTargetId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should close current object before navigating to some other object`() = runTest {
|
||||
|
@ -372,7 +370,7 @@ class ObjectSetNavigationTest : ObjectSetViewModelTestSetup() {
|
|||
afterId = null,
|
||||
beforeId = null,
|
||||
sources = dv.content<DV>().sources,
|
||||
keys = dv.content<DV>().relations.map { it.key },
|
||||
keys = ObjectSearchConstants.defaultKeys + dv.content<DV>().relations.map { it.key },
|
||||
limit = ObjectSetConfig.DEFAULT_LIMIT,
|
||||
offset = 0,
|
||||
result = SearchResult(
|
||||
|
@ -441,231 +439,233 @@ class ObjectSetNavigationTest : ObjectSetViewModelTestSetup() {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `should not emit any navigation command for opening an object contained in given relation if object's layout is not supported`() = runTest {
|
||||
fun `should not emit any navigation command for opening an object contained in given relation if object's layout is not supported`() =
|
||||
runTest {
|
||||
|
||||
// SETUP
|
||||
// SETUP
|
||||
|
||||
val unsupportedLayouis = ObjectType.Layout.values().toList() - SupportedLayouts.layouts
|
||||
val unsupportedLayouis = ObjectType.Layout.values().toList() - SupportedLayouts.layouts
|
||||
|
||||
val linkedProjectTargetId = "Linked project ID"
|
||||
val firstRecordId = "First record ID"
|
||||
val linkedProjectTargetId = "Linked project ID"
|
||||
val firstRecordId = "First record ID"
|
||||
|
||||
val record = mapOf(
|
||||
Relations.ID to firstRecordId,
|
||||
linkedProjectRelation.key to linkedProjectTargetId
|
||||
)
|
||||
val obj = ObjectWrapper.Basic(record)
|
||||
val linkedObject = ObjectWrapper.Basic(
|
||||
mapOf(
|
||||
Relations.ID to linkedProjectTargetId,
|
||||
Relations.NAME to MockDataFactory.randomString(),
|
||||
Relations.LAYOUT to ObjectType.Layout.BASIC
|
||||
val record = mapOf(
|
||||
Relations.ID to firstRecordId,
|
||||
linkedProjectRelation.key to linkedProjectTargetId
|
||||
)
|
||||
)
|
||||
|
||||
val details = Block.Details(
|
||||
details = mapOf(
|
||||
linkedProjectTargetId to Block.Fields(
|
||||
mapOf(
|
||||
Relations.ID to linkedProjectTargetId,
|
||||
Relations.LAYOUT to unsupportedLayouis.random().code.toDouble()
|
||||
)
|
||||
val obj = ObjectWrapper.Basic(record)
|
||||
val linkedObject = ObjectWrapper.Basic(
|
||||
mapOf(
|
||||
Relations.ID to linkedProjectTargetId,
|
||||
Relations.NAME to MockDataFactory.randomString(),
|
||||
Relations.LAYOUT to ObjectType.Layout.BASIC
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
stubInterceptEvents()
|
||||
stubInterceptThreadStatus()
|
||||
stubCloseBlock()
|
||||
stubSubscriptionEventChannel()
|
||||
stubSearchWithSubscription(
|
||||
subscription = root,
|
||||
filters = dv.content<DV>().viewers.first().filters,
|
||||
sorts = dv.content<DV>().viewers.first().sorts,
|
||||
afterId = null,
|
||||
beforeId = null,
|
||||
sources = dv.content<DV>().sources,
|
||||
keys = dv.content<DV>().relations.map { it.key },
|
||||
limit = ObjectSetConfig.DEFAULT_LIMIT,
|
||||
offset = 0,
|
||||
result = SearchResult(
|
||||
results = listOf(obj),
|
||||
dependencies = listOf(linkedObject),
|
||||
counter = SearchResult.Counter(
|
||||
total = 1,
|
||||
prev = 0,
|
||||
next = 0
|
||||
)
|
||||
)
|
||||
)
|
||||
stubOpenObjectSet(
|
||||
doc = listOf(
|
||||
header,
|
||||
title,
|
||||
dv.copy(
|
||||
content = dv.content<DV>().copy(
|
||||
relations = listOf(
|
||||
linkedProjectRelation.copy(
|
||||
isReadOnly = true
|
||||
)
|
||||
val details = Block.Details(
|
||||
details = mapOf(
|
||||
linkedProjectTargetId to Block.Fields(
|
||||
mapOf(
|
||||
Relations.ID to linkedProjectTargetId,
|
||||
Relations.LAYOUT to unsupportedLayouis.random().code.toDouble()
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
dataViewRestrictions = emptyList(),
|
||||
details = details
|
||||
)
|
||||
|
||||
val vm = givenViewModel()
|
||||
|
||||
vm.onStart(root)
|
||||
|
||||
// TESTING
|
||||
|
||||
vm.currentViewer.test {
|
||||
val stateBeforeLoaded = awaitItem()
|
||||
|
||||
assertIs<Viewer.GridView>(stateBeforeLoaded)
|
||||
|
||||
assertEquals(
|
||||
expected = 0,
|
||||
actual = stateBeforeLoaded.rows.size
|
||||
)
|
||||
|
||||
assertIs<Viewer.GridView>(stateBeforeLoaded)
|
||||
|
||||
val stateAfterLoaded = awaitItem()
|
||||
|
||||
assertIs<Viewer.GridView>(stateAfterLoaded)
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = stateAfterLoaded.rows.size
|
||||
)
|
||||
|
||||
// Clicking on cell with linked projects.
|
||||
|
||||
val testObserver = vm.navigation.test()
|
||||
|
||||
vm.onGridCellClicked(stateAfterLoaded.rows.first().cells.last())
|
||||
|
||||
testObserver.assertNoValue()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should emit navigation command opening an object set contained in given relation if this relation is read-only`() = runTest {
|
||||
|
||||
// SETUP
|
||||
|
||||
val linkedProjectTargetId = "Linked project ID"
|
||||
val firstRecordId = "First record ID"
|
||||
|
||||
val record = mapOf(
|
||||
Relations.ID to firstRecordId,
|
||||
linkedProjectRelation.key to linkedProjectTargetId
|
||||
)
|
||||
val obj = ObjectWrapper.Basic(record)
|
||||
val linkedObject = ObjectWrapper.Basic(
|
||||
mapOf(
|
||||
Relations.ID to linkedProjectTargetId,
|
||||
Relations.NAME to MockDataFactory.randomString(),
|
||||
Relations.LAYOUT to ObjectType.Layout.BASIC
|
||||
)
|
||||
)
|
||||
|
||||
val details = Block.Details(
|
||||
details = mapOf(
|
||||
linkedProjectTargetId to Block.Fields(
|
||||
mapOf(
|
||||
Relations.ID to linkedProjectTargetId,
|
||||
Relations.LAYOUT to ObjectType.Layout.SET.code.toDouble()
|
||||
stubInterceptEvents()
|
||||
stubInterceptThreadStatus()
|
||||
stubCloseBlock()
|
||||
stubSubscriptionEventChannel()
|
||||
stubSearchWithSubscription(
|
||||
subscription = root,
|
||||
filters = dv.content<DV>().viewers.first().filters,
|
||||
sorts = dv.content<DV>().viewers.first().sorts,
|
||||
afterId = null,
|
||||
beforeId = null,
|
||||
sources = dv.content<DV>().sources,
|
||||
keys = ObjectSearchConstants.defaultKeys + dv.content<DV>().relations.map { it.key },
|
||||
limit = ObjectSetConfig.DEFAULT_LIMIT,
|
||||
offset = 0,
|
||||
result = SearchResult(
|
||||
results = listOf(obj),
|
||||
dependencies = listOf(linkedObject),
|
||||
counter = SearchResult.Counter(
|
||||
total = 1,
|
||||
prev = 0,
|
||||
next = 0
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
stubInterceptEvents()
|
||||
stubInterceptThreadStatus()
|
||||
stubCloseBlock()
|
||||
stubSubscriptionEventChannel()
|
||||
stubSearchWithSubscription(
|
||||
subscription = root,
|
||||
filters = dv.content<DV>().viewers.first().filters,
|
||||
sorts = dv.content<DV>().viewers.first().sorts,
|
||||
afterId = null,
|
||||
beforeId = null,
|
||||
sources = dv.content<DV>().sources,
|
||||
keys = dv.content<DV>().relations.map { it.key },
|
||||
limit = ObjectSetConfig.DEFAULT_LIMIT,
|
||||
offset = 0,
|
||||
result = SearchResult(
|
||||
results = listOf(obj),
|
||||
dependencies = listOf(linkedObject),
|
||||
counter = SearchResult.Counter(
|
||||
total = 1,
|
||||
prev = 0,
|
||||
next = 0
|
||||
)
|
||||
)
|
||||
)
|
||||
stubOpenObjectSet(
|
||||
doc = listOf(
|
||||
header,
|
||||
title,
|
||||
dv.copy(
|
||||
content = dv.content<DV>().copy(
|
||||
relations = listOf(
|
||||
linkedProjectRelation.copy(
|
||||
isReadOnly = true
|
||||
stubOpenObjectSet(
|
||||
doc = listOf(
|
||||
header,
|
||||
title,
|
||||
dv.copy(
|
||||
content = dv.content<DV>().copy(
|
||||
relations = listOf(
|
||||
linkedProjectRelation.copy(
|
||||
isReadOnly = true
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
dataViewRestrictions = emptyList(),
|
||||
details = details
|
||||
)
|
||||
|
||||
val vm = givenViewModel()
|
||||
|
||||
vm.onStart(root)
|
||||
|
||||
// TESTING
|
||||
|
||||
vm.currentViewer.test {
|
||||
val stateBeforeLoaded = awaitItem()
|
||||
|
||||
assertIs<Viewer.GridView>(stateBeforeLoaded)
|
||||
|
||||
assertEquals(
|
||||
expected = 0,
|
||||
actual = stateBeforeLoaded.rows.size
|
||||
)
|
||||
),
|
||||
dataViewRestrictions = emptyList(),
|
||||
details = details
|
||||
)
|
||||
|
||||
val vm = givenViewModel()
|
||||
assertIs<Viewer.GridView>(stateBeforeLoaded)
|
||||
|
||||
vm.onStart(root)
|
||||
val stateAfterLoaded = awaitItem()
|
||||
|
||||
// TESTING
|
||||
assertIs<Viewer.GridView>(stateAfterLoaded)
|
||||
|
||||
vm.currentViewer.test {
|
||||
val stateBeforeLoaded = awaitItem()
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = stateAfterLoaded.rows.size
|
||||
)
|
||||
|
||||
assertIs<Viewer.GridView>(stateBeforeLoaded)
|
||||
// Clicking on cell with linked projects.
|
||||
|
||||
assertEquals(
|
||||
expected = 0,
|
||||
actual = stateBeforeLoaded.rows.size
|
||||
)
|
||||
val testObserver = vm.navigation.test()
|
||||
|
||||
assertIs<Viewer.GridView>(stateBeforeLoaded)
|
||||
vm.onGridCellClicked(stateAfterLoaded.rows.first().cells.last())
|
||||
|
||||
val stateAfterLoaded = awaitItem()
|
||||
|
||||
assertIs<Viewer.GridView>(stateAfterLoaded)
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = stateAfterLoaded.rows.size
|
||||
)
|
||||
|
||||
// Clicking on cell with linked projects.
|
||||
|
||||
val testObserver = vm.navigation.test()
|
||||
|
||||
vm.onGridCellClicked(stateAfterLoaded.rows.first().cells.last())
|
||||
|
||||
testObserver.assertValue { value ->
|
||||
val content = value.peekContent()
|
||||
content == AppNavigation.Command.OpenObjectSet(linkedProjectTargetId)
|
||||
testObserver.assertNoValue()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should emit navigation command opening an object set contained in given relation if this relation is read-only`() =
|
||||
runTest {
|
||||
|
||||
// SETUP
|
||||
|
||||
val linkedProjectTargetId = "Linked project ID"
|
||||
val firstRecordId = "First record ID"
|
||||
|
||||
val record = mapOf(
|
||||
Relations.ID to firstRecordId,
|
||||
linkedProjectRelation.key to linkedProjectTargetId
|
||||
)
|
||||
val obj = ObjectWrapper.Basic(record)
|
||||
val linkedObject = ObjectWrapper.Basic(
|
||||
mapOf(
|
||||
Relations.ID to linkedProjectTargetId,
|
||||
Relations.NAME to MockDataFactory.randomString(),
|
||||
Relations.LAYOUT to ObjectType.Layout.BASIC
|
||||
)
|
||||
)
|
||||
|
||||
val details = Block.Details(
|
||||
details = mapOf(
|
||||
linkedProjectTargetId to Block.Fields(
|
||||
mapOf(
|
||||
Relations.ID to linkedProjectTargetId,
|
||||
Relations.LAYOUT to ObjectType.Layout.SET.code.toDouble()
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
stubInterceptEvents()
|
||||
stubInterceptThreadStatus()
|
||||
stubCloseBlock()
|
||||
stubSubscriptionEventChannel()
|
||||
stubSearchWithSubscription(
|
||||
subscription = root,
|
||||
filters = dv.content<DV>().viewers.first().filters,
|
||||
sorts = dv.content<DV>().viewers.first().sorts,
|
||||
afterId = null,
|
||||
beforeId = null,
|
||||
sources = dv.content<DV>().sources,
|
||||
keys = ObjectSearchConstants.defaultKeys + dv.content<DV>().relations.map { it.key },
|
||||
limit = ObjectSetConfig.DEFAULT_LIMIT,
|
||||
offset = 0,
|
||||
result = SearchResult(
|
||||
results = listOf(obj),
|
||||
dependencies = listOf(linkedObject),
|
||||
counter = SearchResult.Counter(
|
||||
total = 1,
|
||||
prev = 0,
|
||||
next = 0
|
||||
)
|
||||
)
|
||||
)
|
||||
stubOpenObjectSet(
|
||||
doc = listOf(
|
||||
header,
|
||||
title,
|
||||
dv.copy(
|
||||
content = dv.content<DV>().copy(
|
||||
relations = listOf(
|
||||
linkedProjectRelation.copy(
|
||||
isReadOnly = true
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
dataViewRestrictions = emptyList(),
|
||||
details = details
|
||||
)
|
||||
|
||||
val vm = givenViewModel()
|
||||
|
||||
vm.onStart(root)
|
||||
|
||||
// TESTING
|
||||
|
||||
vm.currentViewer.test {
|
||||
val stateBeforeLoaded = awaitItem()
|
||||
|
||||
assertIs<Viewer.GridView>(stateBeforeLoaded)
|
||||
|
||||
assertEquals(
|
||||
expected = 0,
|
||||
actual = stateBeforeLoaded.rows.size
|
||||
)
|
||||
|
||||
assertIs<Viewer.GridView>(stateBeforeLoaded)
|
||||
|
||||
val stateAfterLoaded = awaitItem()
|
||||
|
||||
assertIs<Viewer.GridView>(stateAfterLoaded)
|
||||
|
||||
assertEquals(
|
||||
expected = 1,
|
||||
actual = stateAfterLoaded.rows.size
|
||||
)
|
||||
|
||||
// Clicking on cell with linked projects.
|
||||
|
||||
val testObserver = vm.navigation.test()
|
||||
|
||||
vm.onGridCellClicked(stateAfterLoaded.rows.first().cells.last())
|
||||
|
||||
testObserver.assertValue { value ->
|
||||
val content = value.peekContent()
|
||||
content == AppNavigation.Command.OpenObjectSet(linkedProjectTargetId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should close editor and navigate to page screen - when page is created`() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue