1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-08 05:47:05 +09:00

DROID-1030 Collection | Enhancement | Order of objects (#3036)

* DROID-1030 objectOrders model, added to data view content

* DROID-1030 grid order

* DROID-1030 gallery order

* DROID-1030 list order

* DROID-1030 get object order by view id

* DROID-1030 refactoring

* DROID-1030 update old tests

* DROID-1030 object order tests by view
This commit is contained in:
Konstantin Ivanov 2023-03-23 13:38:30 +01:00 committed by GitHub
parent b575ae9264
commit 326599d065
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 626 additions and 108 deletions

View file

@ -288,7 +288,8 @@ data class Block(
val viewers: List<Viewer>,
val relationLinks: List<RelationLink> = emptyList(),
val targetObjectId: Id = "",
val isCollection: Boolean = false
val isCollection: Boolean = false,
val objectOrders: List<ObjectOrder> = emptyList()
) : Content() {
data class Viewer(

View file

@ -0,0 +1,7 @@
package com.anytypeio.anytype.core_models
data class ObjectOrder(
val view: Id,
val group: Id,
val ids: List<Id>
)

View file

@ -47,6 +47,7 @@ typealias MDVFilterUpdate = anytype.Event.Block.Dataview.ViewUpdate.Filter
typealias MDVSortUpdate = anytype.Event.Block.Dataview.ViewUpdate.Sort
typealias MDVRelationUpdate = anytype.Event.Block.Dataview.ViewUpdate.Relation
typealias MDVViewFields = anytype.Event.Block.Dataview.ViewUpdate.Fields
typealias MDVObjectOrder = anytype.model.Block.Content.Dataview.ObjectOrder
typealias MObjectType = anytype.model.ObjectType
typealias MSmartBlockType = anytype.model.SmartBlockType

View file

@ -354,7 +354,16 @@ fun MBlock.toCoreModelsDataView(): Block.Content.DataView {
viewers = content.views.map { it.toCoreModels() },
relationLinks = content.relationLinks.map { it.toCoreModels() },
targetObjectId = content.TargetObjectId,
isCollection = content.isCollection
isCollection = content.isCollection,
objectOrders = content.objectOrders.map { it.toCoreModelsObjectOrder() }
)
}
fun MDVObjectOrder.toCoreModelsObjectOrder(): ObjectOrder {
return ObjectOrder(
view = viewId,
group = groupId,
ids = objectIds
)
}

View file

@ -76,7 +76,8 @@ suspend fun DVViewer.render(
objects: List<Id>,
details: Map<Id, Block.Fields>,
dataViewRelations: List<ObjectWrapper.Relation>,
store: ObjectStore
store: ObjectStore,
objectOrderIds: List<Id> = emptyList()
): Viewer {
return when (type) {
DVViewerType.GRID -> {
@ -85,7 +86,8 @@ suspend fun DVViewer.render(
objects = objects,
details = details,
builder = builder,
store = store
store = store,
objectOrderIds = objectOrderIds
)
}
DVViewerType.GALLERY -> {
@ -97,7 +99,8 @@ suspend fun DVViewer.render(
relations = dataViewRelations,
coverImageHashProvider = coverImageHashProvider,
urlBuilder = builder,
objectStore = store
objectStore = store,
objectOrderIds = objectOrderIds
),
title = name,
largeCards = cardSize != DVViewerCardSize.SMALL
@ -116,7 +119,8 @@ suspend fun DVViewer.render(
details = details,
relations = visibleRelations,
urlBuilder = builder,
store = store
store = store,
objectOrderIds = objectOrderIds
),
title = name
)
@ -128,7 +132,8 @@ suspend fun DVViewer.render(
objects = objects,
details = details,
builder = builder,
store = store
store = store,
objectOrderIds = objectOrderIds
)
} else {
Viewer.Unsupported(
@ -141,12 +146,18 @@ suspend fun DVViewer.render(
}
}
private fun List<Viewer.GridView.Row>.sortObjects(objectOrderIds: List<Id>): List<Viewer.GridView.Row> {
val orderMap = objectOrderIds.mapIndexed { index, id -> id to index }.toMap()
return sortedBy { orderMap[it.id] }
}
private suspend fun DVViewer.buildGridView(
dataViewRelations: List<ObjectWrapper.Relation>,
objects: List<Id>,
details: Map<Id, Block.Fields>,
builder: UrlBuilder,
store: ObjectStore
store: ObjectStore,
objectOrderIds: List<Id>
): Viewer {
val vmap = viewerRelations.associateBy { it.key }
val visibleRelations = dataViewRelations.filter { relation ->
@ -173,7 +184,7 @@ private suspend fun DVViewer.buildGridView(
id = id,
name = name,
columns = columns,
rows = rows
rows = if (objectOrderIds.isNotEmpty()) rows.sortObjects(objectOrderIds) else rows
)
}

View file

@ -30,7 +30,8 @@ suspend fun DVViewer.buildGalleryViews(
details: Map<Id, Block.Fields>,
coverImageHashProvider: CoverImageHashProvider,
urlBuilder: UrlBuilder,
objectStore: ObjectStore
objectStore: ObjectStore,
objectOrderIds: List<Id>
): List<Viewer.GalleryView.Item> {
val filteredRelations = viewerRelations.mapNotNull { setting ->
@ -43,6 +44,8 @@ suspend fun DVViewer.buildGalleryViews(
val hasCover = !coverRelationKey.isNullOrEmpty()
val orderMap = objectOrderIds.mapIndexed { index, id -> id to index }.toMap()
return objectIds
.mapNotNull { objectStore.get(it) }
.map { obj ->
@ -67,6 +70,7 @@ suspend fun DVViewer.buildGalleryViews(
)
}
}
.sortedBy { item -> orderMap[item.objectId] }
}
private suspend fun ObjectWrapper.Basic.mapToDefaultItem(

View file

@ -18,81 +18,94 @@ suspend fun DVViewer.buildListViews(
details: Map<Id, Block.Fields>,
urlBuilder: UrlBuilder,
store: ObjectStore,
): List<Viewer.ListView.Item> = objects.mapNotNull { id ->
val obj = store.get(id)
if (obj != null) {
when (obj.layout) {
ObjectType.Layout.BASIC,
ObjectType.Layout.SET,
ObjectType.Layout.COLLECTION,
ObjectType.Layout.OBJECT_TYPE,
ObjectType.Layout.RELATION,
ObjectType.Layout.FILE,
ObjectType.Layout.IMAGE,
ObjectType.Layout.NOTE,
ObjectType.Layout.BOOKMARK -> {
Viewer.ListView.Item.Default(
objectId = obj.id,
relations = obj.valuesFilteredByHidden(
relations = relations,
urlBuilder = urlBuilder,
details = details,
settings = viewerRelations,
storeOfObjects = store
),
name = obj.getProperName(),
icon = ObjectIcon.from(
obj = obj,
layout = obj.layout,
builder = urlBuilder
),
description = obj.description,
hideIcon = hideIcon
)
objectOrderIds: List<Id>
): List<Viewer.ListView.Item> {
val items = objects.mapNotNull { id ->
val obj = store.get(id)
if (obj != null) {
when (obj.layout) {
ObjectType.Layout.BASIC,
ObjectType.Layout.SET,
ObjectType.Layout.COLLECTION,
ObjectType.Layout.OBJECT_TYPE,
ObjectType.Layout.RELATION,
ObjectType.Layout.FILE,
ObjectType.Layout.IMAGE,
ObjectType.Layout.NOTE,
ObjectType.Layout.BOOKMARK -> {
Viewer.ListView.Item.Default(
objectId = obj.id,
relations = obj.valuesFilteredByHidden(
relations = relations,
urlBuilder = urlBuilder,
details = details,
settings = viewerRelations,
storeOfObjects = store
),
name = obj.getProperName(),
icon = ObjectIcon.from(
obj = obj,
layout = obj.layout,
builder = urlBuilder
),
description = obj.description,
hideIcon = hideIcon
)
}
ObjectType.Layout.PROFILE -> {
Viewer.ListView.Item.Profile(
objectId = obj.id,
relations = obj.valuesFilteredByHidden(
relations = relations,
urlBuilder = urlBuilder,
details = details,
settings = viewerRelations,
storeOfObjects = store
),
name = obj.getProperName(),
icon = ObjectIcon.from(
obj = obj,
layout = obj.layout,
builder = urlBuilder
),
description = obj.description,
hideIcon = hideIcon
)
}
ObjectType.Layout.TODO -> {
Viewer.ListView.Item.Task(
objectId = obj.id,
relations = obj.valuesFilteredByHidden(
relations = relations,
urlBuilder = urlBuilder,
details = details,
settings = viewerRelations,
storeOfObjects = store
),
name = obj.getProperName(),
icon = ObjectIcon.from(
obj = obj,
layout = obj.layout,
builder = urlBuilder
),
description = obj.description,
hideIcon = hideIcon
)
}
else -> null
}
ObjectType.Layout.PROFILE -> {
Viewer.ListView.Item.Profile(
objectId = obj.id,
relations = obj.valuesFilteredByHidden(
relations = relations,
urlBuilder = urlBuilder,
details = details,
settings = viewerRelations,
storeOfObjects = store
),
name = obj.getProperName(),
icon = ObjectIcon.from(
obj = obj,
layout = obj.layout,
builder = urlBuilder
),
description = obj.description,
hideIcon = hideIcon
)
}
ObjectType.Layout.TODO -> {
Viewer.ListView.Item.Task(
objectId = obj.id,
relations = obj.valuesFilteredByHidden(
relations = relations,
urlBuilder = urlBuilder,
details = details,
settings = viewerRelations,
storeOfObjects = store
),
name = obj.getProperName(),
icon = ObjectIcon.from(
obj = obj,
layout = obj.layout,
builder = urlBuilder
),
description = obj.description,
hideIcon = hideIcon
)
}
else -> null
} else {
null
}
} else {
null
}
return if (objectOrderIds.isNotEmpty()) {
items.sortObjects(objectOrderIds)
} else {
items
}
}
private fun List<Viewer.ListView.Item>.sortObjects(objectOrderIds: List<Id>): List<Viewer.ListView.Item> {
val orderMap = objectOrderIds.mapIndexed { index, id -> id to index }.toMap()
return sortedBy { orderMap[it.objectId] }
}

View file

@ -194,6 +194,10 @@ fun ObjectState.DataView.viewerById(currentViewerId: String?): DVViewer? {
?: dataViewContent.viewers.firstOrNull()
}
fun ObjectState.DataView.Collection.getObjectOrderIds(currentViewerId: String): List<Id> {
return dataViewContent.objectOrders.find { it.view == currentViewerId }?.ids ?: emptyList()
}
suspend fun List<DVFilter>.updateFormatForSubscription(storeOfRelations: StoreOfRelations): List<DVFilter> {
return map { f: DVFilter ->
val r = storeOfRelations.getByKey(f.relation)

View file

@ -403,15 +403,21 @@ class ObjectSetViewModel(
state.dataViewContent.relationLinks.mapNotNull {
storeOfRelations.getByKey(it.key)
}
val viewer = state.viewerById(currentViewId)
?.render(
val dvViewer = state.viewerById(currentViewId)
val viewer = if (dvViewer != null) {
val objectOrderIds = state.getObjectOrderIds(dvViewer.id)
dvViewer.render(
coverImageHashProvider = coverImageHashProvider,
builder = urlBuilder,
objects = db.objects,
dataViewRelations = relations,
details = state.details,
store = objectStore
store = objectStore,
objectOrderIds = objectOrderIds
)
} else {
null
}
when {
viewer == null -> DataViewViewState.Collection.NoView
viewer.isEmpty() -> DataViewViewState.Collection.NoItems(title = viewer.title)

View file

@ -115,7 +115,7 @@ class CollectionAddRelationTest : ObjectSetViewModelTestSetup() {
val noItemsState = awaitItem()
assertEquals(
expected = DataViewViewState.Collection.NoItems(title = objectCollection.viewer.name),
expected = DataViewViewState.Collection.NoItems(title = objectCollection.viewerList.name),
actual = noItemsState
)
@ -123,8 +123,8 @@ class CollectionAddRelationTest : ObjectSetViewModelTestSetup() {
assertEquals(
expected = DataViewViewState.Collection.Default(
viewer = Viewer.ListView(
id = objectCollection.viewer.id,
title = objectCollection.viewer.name,
id = objectCollection.viewerList.id,
title = objectCollection.viewerList.name,
items = listOf(
Viewer.ListView.Item.Default(
objectId = objectCollection.obj1.id,
@ -220,7 +220,7 @@ class CollectionAddRelationTest : ObjectSetViewModelTestSetup() {
val eventDataViewUpdateView = Event.Command.DataView.UpdateView(
context = root,
block = objectCollection.dataView.id,
viewerId = objectCollection.viewer.id,
viewerId = objectCollection.viewerList.id,
relationUpdates = listOf(
Event.Command.DataView.UpdateView.DVViewerRelationUpdate.Add(
afterId = objectCollection.relationObject2.id,
@ -231,6 +231,15 @@ class CollectionAddRelationTest : ObjectSetViewModelTestSetup() {
filterUpdates = listOf(),
sortUpdates = listOf()
)
stubSubscriptionResults(
subscription = objectCollection.subscriptionId,
collection = root,
workspace = objectCollection.workspaceId,
storeOfRelations = storeOfRelations,
keys = objectCollection.dvKeys + relationObject4.key,
objects = listOf(objectCollection.obj1, objectCollection.obj2),
dvSorts = objectCollection.sorts
)
dispatcher.send(
Payload(
context = root,
@ -244,7 +253,7 @@ class CollectionAddRelationTest : ObjectSetViewModelTestSetup() {
val second = awaitItem()
val expectedView = objectCollection.viewer.copy(
val expectedView = objectCollection.viewerList.copy(
viewerRelations = listOf(
objectCollection.dvViewerRelation1,
objectCollection.dvViewerRelation2,
@ -261,6 +270,9 @@ class CollectionAddRelationTest : ObjectSetViewModelTestSetup() {
objectCollection.relationLink1,
objectCollection.relationLink2,
objectCollection.relationLink3,
objectCollection.relationLink4,
objectCollection.relationLink5,
objectCollection.relationLink6,
relationLink4
)
)

View file

@ -78,7 +78,7 @@ class CollectionDataViewUpdateTest : ObjectSetViewModelTestSetup() {
val eventDVUpdate = Event.Command.DataView.UpdateView(
context = objectCollection.root,
block = objectCollection.dataView.id,
viewerId = objectCollection.viewer.id,
viewerId = objectCollection.viewerList.id,
sortUpdates = listOf(
Event.Command.DataView.UpdateView.DVSortUpdate.Update(
id = objectCollection.sort1.id,

View file

@ -4,6 +4,7 @@ import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.DVSort
import com.anytypeio.anytype.core_models.DVSortType
import com.anytypeio.anytype.core_models.DVViewerType
import com.anytypeio.anytype.core_models.ObjectOrder
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.Relation
import com.anytypeio.anytype.core_models.Relations
@ -16,7 +17,6 @@ import com.anytypeio.anytype.core_models.StubRelationLink
import com.anytypeio.anytype.core_models.StubRelationObject
import com.anytypeio.anytype.core_models.StubTitle
import com.anytypeio.anytype.presentation.sets.subscription.DefaultDataViewSubscription
import net.bytebuddy.asm.Advice.OffsetMapping.Sort
import net.bytebuddy.utility.RandomString
class MockCollection(context: String) {
@ -40,6 +40,21 @@ class MockCollection(context: String) {
isReadOnlyValue = false,
format = Relation.Format.TAG
)
val relationObject4 = StubRelationObject(
key = "relationStatus-${RandomString.make()}",
isReadOnlyValue = false,
format = Relation.Format.STATUS
)
val relationObject5 = StubRelationObject(
key = "relationObject-${RandomString.make()}",
isReadOnlyValue = false,
format = Relation.Format.OBJECT
)
val relationObject6 = StubRelationObject(
key = "relationNumber-${RandomString.make()}",
isReadOnlyValue = false,
format = Relation.Format.NUMBER
)
// VIEW RELATIONS
val dvViewerRelation1 =
@ -48,17 +63,29 @@ class MockCollection(context: String) {
StubDataViewViewRelation(key = relationObject2.key, isVisible = true)
val dvViewerRelation3 =
StubDataViewViewRelation(key = relationObject3.key, isVisible = true)
val dvViewerRelation4 =
StubDataViewViewRelation(key = relationObject4.key, isVisible = true)
val dvViewerRelation5 =
StubDataViewViewRelation(key = relationObject5.key, isVisible = true)
val dvViewerRelation6 =
StubDataViewViewRelation(key = relationObject6.key, isVisible = true)
// RELATION LINKS
val relationLink1 = StubRelationLink(relationObject1.key)
val relationLink2 = StubRelationLink(relationObject2.key)
val relationLink3 = StubRelationLink(relationObject3.key)
val relationLink4 = StubRelationLink(relationObject4.key)
val relationLink5 = StubRelationLink(relationObject5.key)
val relationLink6 = StubRelationLink(relationObject6.key)
// SEARCH OBJECTS COMMAND, RELATION KEYS
val dvKeys = listOf(
relationObject1.key,
relationObject2.key,
relationObject3.key
relationObject3.key,
relationObject4.key,
relationObject5.key,
relationObject6.key
)
// SORTS
@ -67,23 +94,106 @@ class MockCollection(context: String) {
relationKey = relationObject1.key,
type = DVSortType.ASC
)
val sortGrid = DVSort(
id = "sortId-${RandomString.make()}",
relationKey = relationObject5.key,
type = DVSortType.DESC
)
val sortGallery = DVSort(
id = "sortId-${RandomString.make()}",
relationKey = relationObject6.key,
type = DVSortType.DESC
)
val sorts = listOf(sort1)
val viewer =
StubDataViewView(
id = "dvViewer-${RandomString.make()}",
viewerRelations = listOf(dvViewerRelation1, dvViewerRelation2, dvViewerRelation3),
type = DVViewerType.LIST,
sorts = sorts
val viewerList = StubDataViewView(
id = "dvViewerList-${RandomString.make()}",
viewerRelations = listOf(dvViewerRelation1, dvViewerRelation2, dvViewerRelation3),
type = DVViewerType.LIST,
sorts = sorts
)
val viewerGrid = StubDataViewView(
id = "dvViewerGrid-${RandomString.make()}",
viewerRelations = listOf(dvViewerRelation6, dvViewerRelation5, dvViewerRelation3),
type = DVViewerType.GRID,
sorts = listOf(sortGrid)
)
val viewerGallery = StubDataViewView(
id = "dvViewerGallery-${RandomString.make()}",
viewerRelations = listOf(
dvViewerRelation1,
dvViewerRelation2,
dvViewerRelation3,
dvViewerRelation4,
dvViewerRelation5,
dvViewerRelation6
),
type = DVViewerType.GALLERY,
sorts = listOf(sortGallery)
)
val obj1 = StubObject(id = "object1-${RandomString.make()}")
val obj2 = StubObject(id = "object2-${RandomString.make()}")
val obj3 = StubObject(id = "object3-${RandomString.make()}")
val obj4 = StubObject(id = "object4-${RandomString.make()}")
val obj5 = StubObject(id = "object5-${RandomString.make()}")
// 3, 2, 4, 5, 1
val objectOrderList =
ObjectOrder(
view = viewerList.id,
group = "",
ids = listOf(obj3.id, obj2.id, obj4.id, obj5.id, obj1.id)
)
// 1, 2, 4, 3, 5
val objectOrderGrid =
ObjectOrder(
view = viewerGrid.id,
group = "",
ids = listOf(obj1.id, obj2.id, obj4.id, obj3.id, obj5.id)
)
// 5, 4, 3, 2, 1
val objectOrderGallery =
ObjectOrder(
view = viewerGallery.id,
group = "",
ids = listOf(obj5.id, obj4.id, obj3.id, obj2.id, obj1.id)
)
val dataView = StubDataView(
id = "dv-${RandomString.make()}",
views = listOf(viewer),
relationLinks = listOf(relationLink1, relationLink2, relationLink3)
views = listOf(viewerList),
relationLinks = listOf(relationLink1, relationLink2, relationLink3, relationLink4, relationLink5, relationLink6),
isCollection = true,
objectOrder = emptyList()
)
val dataViewGrid = StubDataView(
id = "dv-${RandomString.make()}",
views = listOf(viewerGrid),
relationLinks = listOf(relationLink1, relationLink2, relationLink3, relationLink4, relationLink5, relationLink6),
isCollection = true,
objectOrder = emptyList()
)
val dataViewGallery = StubDataView(
id = "dv-${RandomString.make()}",
views = listOf(viewerGallery),
relationLinks = listOf(relationLink1, relationLink2, relationLink3, relationLink4, relationLink5, relationLink6),
isCollection = true,
objectOrder = emptyList()
)
val dataViewWithObjectOrder = StubDataView(
id = "dv-${RandomString.make()}",
views = listOf(viewerList, viewerGrid, viewerGallery),
relationLinks = listOf(relationLink1, relationLink2, relationLink3, relationLink4, relationLink5, relationLink6),
objectOrder = listOf(objectOrderList, objectOrderGrid, objectOrderGallery),
isCollection = true
)
val workspaceId = "workspace-${RandomString.make()}"
val obj1 = StubObject(id = "object1-${RandomString.make()}")
val obj2 = StubObject(id = "object2-${RandomString.make()}")
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(context)
val details = Block.Details(

View file

@ -4,6 +4,7 @@ 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
import com.anytypeio.anytype.presentation.sets.model.Viewer
import com.anytypeio.anytype.presentation.sets.state.ObjectState
import kotlin.test.assertEquals
import kotlin.test.assertIs
@ -179,4 +180,338 @@ class ObjectStateCollectionViewTest : ObjectSetViewModelTestSetup() {
assertIs<DataViewViewState.Collection.NoItems>(viewerFlow.awaitItem())
assertIs<DataViewViewState.Collection.Default>(viewerFlow.awaitItem())
}
@Test
fun `should sort LIST collection objects by data view object order`() = runTest {
// SETUP
stubWorkspaceManager(mockObjectCollection.workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(
mockObjectCollection.header,
mockObjectCollection.title,
mockObjectCollection.dataViewWithObjectOrder
),
details = mockObjectCollection.details
)
stubStoreOfRelations(mockObjectCollection)
stubSubscriptionResults(
subscription = mockObjectCollection.subscriptionId,
workspace = mockObjectCollection.workspaceId,
collection = root,
storeOfRelations = storeOfRelations,
keys = mockObjectCollection.dvKeys,
objects = listOf(
mockObjectCollection.obj1,
mockObjectCollection.obj2,
mockObjectCollection.obj3,
mockObjectCollection.obj4,
mockObjectCollection.obj5
),
dvSorts = mockObjectCollection.sorts
)
// TESTING
viewModel.onStart(ctx = root)
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
val stateFlow = stateReducer.state.testIn(backgroundScope)
// ASSERT STATES
assertIs<ObjectState.Init>(stateFlow.awaitItem())
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
assertIs<DataViewViewState.Collection.NoItems>(viewerFlow.awaitItem())
assertIs<DataViewViewState.Collection.Default>(viewerFlow.awaitItem()).also {dataViewState ->
val rows = (dataViewState.viewer as Viewer.ListView).items
assertEquals(5, rows.size)
// SHOULD BE 3, 2, 4, 5, 1
assertEquals(mockObjectCollection.obj3.id, rows[0].objectId)
assertEquals(mockObjectCollection.obj2.id, rows[1].objectId)
assertEquals(mockObjectCollection.obj4.id, rows[2].objectId)
assertEquals(mockObjectCollection.obj5.id, rows[3].objectId)
assertEquals(mockObjectCollection.obj1.id, rows[4].objectId)
}
}
@Test
fun `should not sort LIST collection objects by empty data view object order`() = runTest {
// SETUP
stubWorkspaceManager(mockObjectCollection.workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(
mockObjectCollection.header,
mockObjectCollection.title,
mockObjectCollection.dataView
),
details = mockObjectCollection.details
)
stubStoreOfRelations(mockObjectCollection)
stubSubscriptionResults(
subscription = mockObjectCollection.subscriptionId,
workspace = mockObjectCollection.workspaceId,
collection = root,
storeOfRelations = storeOfRelations,
keys = mockObjectCollection.dvKeys,
objects = listOf(
mockObjectCollection.obj5,
mockObjectCollection.obj2,
mockObjectCollection.obj3,
mockObjectCollection.obj4,
mockObjectCollection.obj1
),
dvSorts = mockObjectCollection.sorts
)
// TESTING
viewModel.onStart(ctx = root)
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
val stateFlow = stateReducer.state.testIn(backgroundScope)
// ASSERT STATES
assertIs<ObjectState.Init>(stateFlow.awaitItem())
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
assertIs<DataViewViewState.Collection.NoItems>(viewerFlow.awaitItem())
assertIs<DataViewViewState.Collection.Default>(viewerFlow.awaitItem()).also {dataViewState ->
val rows = (dataViewState.viewer as Viewer.ListView).items
assertEquals(5, rows.size)
// SHOULD BE NOT SORTED 5, 2, 3, 4, 1
assertEquals(mockObjectCollection.obj5.id, rows[0].objectId)
assertEquals(mockObjectCollection.obj2.id, rows[1].objectId)
assertEquals(mockObjectCollection.obj3.id, rows[2].objectId)
assertEquals(mockObjectCollection.obj4.id, rows[3].objectId)
assertEquals(mockObjectCollection.obj1.id, rows[4].objectId)
}
}
@Test
fun `should sort GRID collection objects by data view object order`() = runTest {
// SETUP
session.currentViewerId.value = mockObjectCollection.viewerGrid.id
stubWorkspaceManager(mockObjectCollection.workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(
mockObjectCollection.header,
mockObjectCollection.title,
mockObjectCollection.dataViewWithObjectOrder
),
details = mockObjectCollection.details
)
stubStoreOfRelations(mockObjectCollection)
stubSubscriptionResults(
subscription = mockObjectCollection.subscriptionId,
workspace = mockObjectCollection.workspaceId,
collection = root,
storeOfRelations = storeOfRelations,
keys = mockObjectCollection.dvKeys,
objects = listOf(
mockObjectCollection.obj1,
mockObjectCollection.obj2,
mockObjectCollection.obj3,
mockObjectCollection.obj4,
mockObjectCollection.obj5
),
dvSorts = listOf(mockObjectCollection.sortGrid)
)
// TESTING
viewModel.onStart(ctx = root)
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
val stateFlow = stateReducer.state.testIn(backgroundScope)
// ASSERT STATES
assertIs<ObjectState.Init>(stateFlow.awaitItem())
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
assertIs<DataViewViewState.Collection.NoItems>(viewerFlow.awaitItem())
assertIs<DataViewViewState.Collection.Default>(viewerFlow.awaitItem()).also {dataViewState ->
val rows = (dataViewState.viewer as Viewer.GridView).rows
assertEquals(5, rows.size)
// SHOULD BE SORTED 1, 2, 4, 3, 5
assertEquals(mockObjectCollection.obj1.id, rows[0].id)
assertEquals(mockObjectCollection.obj2.id, rows[1].id)
assertEquals(mockObjectCollection.obj4.id, rows[2].id)
assertEquals(mockObjectCollection.obj3.id, rows[3].id)
assertEquals(mockObjectCollection.obj5.id, rows[4].id)
}
}
@Test
fun `should NOT sort GRID collection objects by empty data view object order`() = runTest {
// SETUP
session.currentViewerId.value = mockObjectCollection.viewerGrid.id
stubWorkspaceManager(mockObjectCollection.workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(
mockObjectCollection.header,
mockObjectCollection.title,
mockObjectCollection.dataViewGrid
),
details = mockObjectCollection.details
)
stubStoreOfRelations(mockObjectCollection)
stubSubscriptionResults(
subscription = mockObjectCollection.subscriptionId,
workspace = mockObjectCollection.workspaceId,
collection = root,
storeOfRelations = storeOfRelations,
keys = mockObjectCollection.dvKeys,
objects = listOf(
mockObjectCollection.obj1,
mockObjectCollection.obj2,
mockObjectCollection.obj3,
mockObjectCollection.obj4,
mockObjectCollection.obj5
),
dvSorts = listOf(mockObjectCollection.sortGrid)
)
// TESTING
viewModel.onStart(ctx = root)
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
val stateFlow = stateReducer.state.testIn(backgroundScope)
// ASSERT STATES
assertIs<ObjectState.Init>(stateFlow.awaitItem())
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
assertIs<DataViewViewState.Collection.NoItems>(viewerFlow.awaitItem())
assertIs<DataViewViewState.Collection.Default>(viewerFlow.awaitItem()).also {dataViewState ->
val rows = (dataViewState.viewer as Viewer.GridView).rows
assertEquals(5, rows.size)
// SHOULD BE SORTED 1, 2, 4, 3, 5
assertEquals(mockObjectCollection.obj1.id, rows[0].id)
assertEquals(mockObjectCollection.obj2.id, rows[1].id)
assertEquals(mockObjectCollection.obj3.id, rows[2].id)
assertEquals(mockObjectCollection.obj4.id, rows[3].id)
assertEquals(mockObjectCollection.obj5.id, rows[4].id)
}
}
@Test
fun `should sort GALLERY collection objects by data view object order`() = runTest {
// SETUP
session.currentViewerId.value = mockObjectCollection.viewerGallery.id
stubWorkspaceManager(mockObjectCollection.workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(
mockObjectCollection.header,
mockObjectCollection.title,
mockObjectCollection.dataViewWithObjectOrder
),
details = mockObjectCollection.details
)
stubStoreOfRelations(mockObjectCollection)
stubSubscriptionResults(
subscription = mockObjectCollection.subscriptionId,
workspace = mockObjectCollection.workspaceId,
collection = root,
storeOfRelations = storeOfRelations,
keys = mockObjectCollection.dvKeys,
objects = listOf(
mockObjectCollection.obj1,
mockObjectCollection.obj2,
mockObjectCollection.obj3,
mockObjectCollection.obj4,
mockObjectCollection.obj5
),
dvSorts = listOf(mockObjectCollection.sortGallery)
)
// TESTING
viewModel.onStart(ctx = root)
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
val stateFlow = stateReducer.state.testIn(backgroundScope)
// ASSERT STATES
assertIs<ObjectState.Init>(stateFlow.awaitItem())
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
assertIs<DataViewViewState.Collection.NoItems>(viewerFlow.awaitItem())
assertIs<DataViewViewState.Collection.Default>(viewerFlow.awaitItem()).also {dataViewState ->
val rows = (dataViewState.viewer as Viewer.GalleryView).items
assertEquals(5, rows.size)
// SHOULD BE SORTED 5, 4, 3, 2, 1
assertEquals(mockObjectCollection.obj5.id, rows[0].objectId)
assertEquals(mockObjectCollection.obj4.id, rows[1].objectId)
assertEquals(mockObjectCollection.obj3.id, rows[2].objectId)
assertEquals(mockObjectCollection.obj2.id, rows[3].objectId)
assertEquals(mockObjectCollection.obj1.id, rows[4].objectId)
}
}
@Test
fun `should NOT sort GALLERY collection objects by empty data view object order`() = runTest {
// SETUP
session.currentViewerId.value = mockObjectCollection.viewerGallery.id
stubWorkspaceManager(mockObjectCollection.workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(
mockObjectCollection.header,
mockObjectCollection.title,
mockObjectCollection.dataViewGallery
),
details = mockObjectCollection.details
)
stubStoreOfRelations(mockObjectCollection)
stubSubscriptionResults(
subscription = mockObjectCollection.subscriptionId,
workspace = mockObjectCollection.workspaceId,
collection = root,
storeOfRelations = storeOfRelations,
keys = mockObjectCollection.dvKeys,
objects = listOf(
mockObjectCollection.obj1,
mockObjectCollection.obj2,
mockObjectCollection.obj3,
mockObjectCollection.obj4,
mockObjectCollection.obj5
),
dvSorts = listOf(mockObjectCollection.sortGallery)
)
// TESTING
viewModel.onStart(ctx = root)
val viewerFlow = viewModel.currentViewer.testIn(backgroundScope)
val stateFlow = stateReducer.state.testIn(backgroundScope)
// ASSERT STATES
assertIs<ObjectState.Init>(stateFlow.awaitItem())
assertIs<DataViewViewState.Init>(viewerFlow.awaitItem())
assertIs<DataViewViewState.Collection.NoItems>(viewerFlow.awaitItem())
assertIs<DataViewViewState.Collection.Default>(viewerFlow.awaitItem()).also {dataViewState ->
val rows = (dataViewState.viewer as Viewer.GalleryView).items
assertEquals(5, rows.size)
// SHOULD BE SORTED 5, 4, 3, 2, 1
assertEquals(mockObjectCollection.obj1.id, rows[0].objectId)
assertEquals(mockObjectCollection.obj2.id, rows[1].objectId)
assertEquals(mockObjectCollection.obj3.id, rows[2].objectId)
assertEquals(mockObjectCollection.obj4.id, rows[3].objectId)
assertEquals(mockObjectCollection.obj5.id, rows[4].objectId)
}
}
}

View file

@ -329,7 +329,10 @@ open class ObjectSetViewModelTestSetup {
listOf(
mockObjectCollection.relationObject1,
mockObjectCollection.relationObject2,
mockObjectCollection.relationObject3
mockObjectCollection.relationObject3,
mockObjectCollection.relationObject4,
mockObjectCollection.relationObject5,
mockObjectCollection.relationObject6
)
)
}

View file

@ -7,14 +7,16 @@ fun StubDataView(
views: List<DVViewer> = emptyList(),
relationLinks: List<RelationLink> = emptyList(),
targetObjectId: Id = MockDataFactory.randomUuid(),
isCollection: Boolean = false
isCollection: Boolean = false,
objectOrder: List<ObjectOrder> = emptyList()
): Block = Block(
id = id,
content = DV(
relationLinks = relationLinks,
viewers = views,
targetObjectId = targetObjectId,
isCollection = isCollection
isCollection = isCollection,
objectOrders = objectOrder
),
children = emptyList(),
fields = Block.Fields.empty()