1
0
Fork 0
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:
Konstantin Ivanov 2022-09-12 11:16:11 +02:00 committed by GitHub
parent 9549371ccb
commit edde39e76a
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 226 additions and 1 deletions

View file

@ -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

View file

@ -32,6 +32,7 @@ class MiddlewareEventChannel(
msg.blockDataviewRecordsSet,
msg.blockDataviewRelationSet,
msg.blockDataviewRecordsUpdate,
msg.blockDataviewRecordsDelete,
msg.blockDataviewViewDelete,
msg.blockDataviewViewSet,
msg.objectRelationsAmend,

View file

@ -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)

View file

@ -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

View file

@ -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 ->

View file

@ -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)
}
}

View file

@ -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
)