mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-316 Set | Delete records from active viewer (#2589)
* DROID-316 delete records event * DROID-316 delete records extension + test Co-authored-by: konstantiniiv <ki@anytype.io>
This commit is contained in:
parent
9549371ccb
commit
edde39e76a
7 changed files with 226 additions and 1 deletions
|
@ -252,6 +252,13 @@ sealed class Event {
|
|||
val records: List<DVRecord>
|
||||
) : DataView()
|
||||
|
||||
data class DeleteRecord(
|
||||
override val context: String,
|
||||
val dataViewId: String,
|
||||
val viewerId: String,
|
||||
val recordIds: List<String>
|
||||
) : DataView()
|
||||
|
||||
/**
|
||||
* Sent when a data-view's view has been changed or added.
|
||||
* @property [target] data view's block id
|
||||
|
|
|
@ -32,6 +32,7 @@ class MiddlewareEventChannel(
|
|||
msg.blockDataviewRecordsSet,
|
||||
msg.blockDataviewRelationSet,
|
||||
msg.blockDataviewRecordsUpdate,
|
||||
msg.blockDataviewRecordsDelete,
|
||||
msg.blockDataviewViewDelete,
|
||||
msg.blockDataviewViewSet,
|
||||
msg.objectRelationsAmend,
|
||||
|
|
|
@ -182,6 +182,16 @@ fun anytype.Event.Message.toCoreModels(
|
|||
records = event.records.map { it?.toMap().orEmpty() },
|
||||
)
|
||||
}
|
||||
blockDataviewRecordsDelete != null -> {
|
||||
val event = blockDataviewRecordsDelete
|
||||
checkNotNull(event)
|
||||
Event.Command.DataView.DeleteRecord(
|
||||
context = context,
|
||||
dataViewId = event.id,
|
||||
viewerId = event.viewId,
|
||||
recordIds = event.removed
|
||||
)
|
||||
}
|
||||
blockSetDiv != null -> {
|
||||
val event = blockSetDiv
|
||||
checkNotNull(event)
|
||||
|
|
|
@ -27,6 +27,29 @@ fun ObjectSet.updateRecord(
|
|||
}
|
||||
}
|
||||
|
||||
fun ObjectSet.deleteRecords(
|
||||
viewer: Id,
|
||||
recordIds: List<String>
|
||||
): ObjectSet {
|
||||
val current = viewerDb[viewer]
|
||||
return if (current != null) {
|
||||
val new = current.records.mapNotNull { rec ->
|
||||
val id = rec[ID_KEY]
|
||||
if (id != null && !recordIds.contains(id)) {
|
||||
rec
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
val updatedRecords = viewerDb.toMutableMap().apply {
|
||||
put(viewer, current.copy(records = new))
|
||||
}
|
||||
this.copy(viewerDb = updatedRecords)
|
||||
} else {
|
||||
this.copy()
|
||||
}
|
||||
}
|
||||
|
||||
fun ObjectSet.featuredRelations(
|
||||
ctx: Id,
|
||||
urlBuilder: UrlBuilder
|
||||
|
|
|
@ -135,6 +135,12 @@ class ObjectSetReducer {
|
|||
is Command.DataView.UpdateRecord -> {
|
||||
state.updateRecord(event.viewer, event.records)
|
||||
}
|
||||
is Command.DataView.DeleteRecord -> {
|
||||
state.deleteRecords(
|
||||
viewer = event.viewerId,
|
||||
recordIds = event.recordIds
|
||||
)
|
||||
}
|
||||
is Command.DataView.SetRelation -> {
|
||||
state.copy(
|
||||
blocks = state.blocks.map { block ->
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
package com.anytypeio.anytype.presentation.sets
|
||||
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import com.anytypeio.anytype.core_models.Event
|
||||
import com.anytypeio.anytype.presentation.TypicalTwoRecordObjectSet
|
||||
import com.anytypeio.anytype.presentation.sets.main.ObjectSetViewModelTestSetup
|
||||
import com.anytypeio.anytype.presentation.sets.model.CellView
|
||||
import com.anytypeio.anytype.presentation.sets.model.Viewer
|
||||
import com.anytypeio.anytype.presentation.util.CoroutinesTestRule
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mockito.MockitoAnnotations
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertIs
|
||||
|
||||
class ObjectSetExtensionTest : ObjectSetViewModelTestSetup() {
|
||||
|
||||
@get:Rule
|
||||
val rule = InstantTaskExecutorRule()
|
||||
|
||||
@get:Rule
|
||||
val coroutineTestRule = CoroutinesTestRule()
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
MockitoAnnotations.openMocks(this)
|
||||
}
|
||||
|
||||
val doc = TypicalTwoRecordObjectSet()
|
||||
|
||||
@Test
|
||||
fun `should delete first record from active view`() {
|
||||
|
||||
// SETUP
|
||||
|
||||
val flow: Flow<List<Event>> = flow {
|
||||
delay(200)
|
||||
emit(
|
||||
listOf(
|
||||
Event.Command.DataView.SetRecords(
|
||||
context = root,
|
||||
view = doc.viewer1.id,
|
||||
id = doc.dv.id,
|
||||
total = MockDataFactory.randomInt(),
|
||||
records = doc.initialRecords
|
||||
)
|
||||
)
|
||||
)
|
||||
delay(200)
|
||||
emit(
|
||||
listOf(
|
||||
Event.Command.DataView.DeleteRecord(
|
||||
context = root,
|
||||
dataViewId = doc.dv.id,
|
||||
viewerId = doc.viewer1.id,
|
||||
recordIds = listOf(doc.firstRecordId)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
stubInterceptEvents(
|
||||
flow = flow
|
||||
)
|
||||
stubOpenObjectSet(
|
||||
doc = listOf(
|
||||
doc.header,
|
||||
doc.title,
|
||||
doc.dv
|
||||
)
|
||||
)
|
||||
stubSetActiveViewer()
|
||||
stubUpdateDataViewViewer()
|
||||
stubInterceptThreadStatus()
|
||||
|
||||
val vm = givenViewModel()
|
||||
|
||||
// TESTING
|
||||
|
||||
vm.onStart(root)
|
||||
|
||||
coroutineTestRule.advanceTime(200)
|
||||
|
||||
val viewerBefore = vm.currentViewer.value
|
||||
|
||||
val expectedRowsBefore = listOf(
|
||||
Viewer.GridView.Row(
|
||||
id = doc.firstRecordId,
|
||||
name = doc.firstRecordName,
|
||||
emoji = null,
|
||||
image = null,
|
||||
type = doc.firstRecordType,
|
||||
showIcon = true,
|
||||
cells = listOf(
|
||||
CellView.Description(
|
||||
id = doc.firstRecordId,
|
||||
text = doc.firstRecord[doc.relations[0].key] as String,
|
||||
key = doc.relations[0].key
|
||||
),
|
||||
CellView.Description(
|
||||
id = doc.firstRecordId,
|
||||
text = doc.firstRecord[doc.relations[1].key] as String,
|
||||
key = doc.relations[1].key
|
||||
)
|
||||
)
|
||||
),
|
||||
Viewer.GridView.Row(
|
||||
id = doc.secondRecordId,
|
||||
name = doc.secondRecordName,
|
||||
emoji = null,
|
||||
image = null,
|
||||
type = doc.secondRecordType,
|
||||
showIcon = true,
|
||||
cells = listOf(
|
||||
CellView.Description(
|
||||
id = doc.secondRecordId,
|
||||
text = doc.secondRecord[doc.relations[0].key] as String,
|
||||
key = doc.relations[0].key
|
||||
),
|
||||
CellView.Description(
|
||||
id = doc.secondRecordId,
|
||||
text = doc.secondRecord[doc.relations[1].key] as String,
|
||||
key = doc.relations[1].key
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
assertIs<Viewer.GridView>(viewerBefore)
|
||||
|
||||
assertEquals(
|
||||
expected = expectedRowsBefore,
|
||||
actual = viewerBefore.rows
|
||||
)
|
||||
|
||||
coroutineTestRule.advanceTime(200)
|
||||
|
||||
val viewerAfter = vm.currentViewer.value
|
||||
|
||||
val expectedRowsAfter = listOf(
|
||||
Viewer.GridView.Row(
|
||||
id = doc.secondRecordId,
|
||||
name = doc.secondRecordName,
|
||||
emoji = null,
|
||||
image = null,
|
||||
type = doc.secondRecordType,
|
||||
showIcon = true,
|
||||
cells = listOf(
|
||||
CellView.Description(
|
||||
id = doc.secondRecordId,
|
||||
text = doc.secondRecord[doc.relations[0].key] as String,
|
||||
key = doc.relations[0].key
|
||||
),
|
||||
CellView.Description(
|
||||
id = doc.secondRecordId,
|
||||
text = doc.secondRecord[doc.relations[1].key] as String,
|
||||
key = doc.relations[1].key
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
assertIs<Viewer.GridView>(viewerAfter)
|
||||
|
||||
assertEquals(
|
||||
expected = expectedRowsAfter,
|
||||
actual = viewerAfter.rows
|
||||
)
|
||||
|
||||
coroutineTestRule.advanceTime(1000)
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ import com.anytypeio.anytype.core_models.ObjectWrapper
|
|||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.core_models.Relation
|
||||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_models.SmartBlockType
|
||||
import com.anytypeio.anytype.core_models.restrictions.DataViewRestrictions
|
||||
import com.anytypeio.anytype.domain.base.Either
|
||||
import com.anytypeio.anytype.domain.base.Result
|
||||
|
@ -174,7 +175,8 @@ open class ObjectSetViewModelTestSetup {
|
|||
details = details,
|
||||
relations = relations,
|
||||
objectTypes = objectTypes,
|
||||
dataViewRestrictions = dataViewRestrictions
|
||||
dataViewRestrictions = dataViewRestrictions,
|
||||
type = SmartBlockType.SET
|
||||
)
|
||||
) + additionalEvents
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue