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

DROID-378 Collections | Open note in editor if it was created from set (#3017)

* DROID-378 create data view object use case, add internal flags

* DROID-378 logic after new object

* DROID-378 mocks + tests

* DROID-378 test fix

* DROID-378 ci

* DROID-378 сш щаа
This commit is contained in:
Konstantin Ivanov 2023-03-16 10:21:54 +01:00 committed by GitHub
parent 5ecd1ec0ac
commit 94a887c3a2
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 302 additions and 25 deletions

View file

@ -189,7 +189,8 @@ abstract class TestObjectSetSetup {
getTemplates = getTemplates,
repo = repo,
storeOfRelations = storeOfRelations,
getDefaultPageType = getDefaultPageType
getDefaultPageType = getDefaultPageType,
dispatchers = dispatchers
)
setObjectDetails = UpdateDetail(repo)
updateDataViewViewer = UpdateDataViewViewer(repo)

View file

@ -277,12 +277,14 @@ object ObjectSetModule {
repo: BlockRepository,
storeOfRelations: StoreOfRelations,
getDefaultPageType: GetDefaultPageType,
getTemplates: GetTemplates
getTemplates: GetTemplates,
dispatchers: AppCoroutineDispatchers
): CreateDataViewObject = CreateDataViewObject(
repo = repo,
getDefaultPageType = getDefaultPageType,
getTemplates = getTemplates,
storeOfRelations = storeOfRelations
storeOfRelations = storeOfRelations,
dispatchers = dispatchers
)
@JvmStatic

View file

@ -11,7 +11,8 @@ import com.anytypeio.anytype.core_models.Relation
import com.anytypeio.anytype.core_models.RelationFormat
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.Struct
import com.anytypeio.anytype.domain.base.BaseUseCase
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
import com.anytypeio.anytype.domain.base.ResultInteractor
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.launch.GetDefaultPageType
import com.anytypeio.anytype.domain.objects.StoreOfRelations
@ -24,11 +25,12 @@ class CreateDataViewObject(
private val repo: BlockRepository,
private val getTemplates: GetTemplates,
private val getDefaultPageType: GetDefaultPageType,
private val storeOfRelations: StoreOfRelations
) : BaseUseCase<Id, CreateDataViewObject.Params>() {
private val storeOfRelations: StoreOfRelations,
dispatchers: AppCoroutineDispatchers
) : ResultInteractor<CreateDataViewObject.Params, Id>(dispatchers.io) {
override suspend fun run(params: Params) = safe {
when (params) {
override suspend fun doWork(params: Params): Id {
return when (params) {
is Params.SetByType -> {
val command = Command.CreateObject(
template = resolveTemplateForNewObject(type = params.type),
@ -36,7 +38,7 @@ class CreateDataViewObject(
filters = params.filters,
type = params.type
),
internalFlags = listOf()
internalFlags = listOf(InternalFlags.ShouldSelectTemplate)
)
val result = repo.createObject(command)
result.id
@ -50,7 +52,7 @@ class CreateDataViewObject(
relations = params.relations,
type = type
),
internalFlags = listOf()
internalFlags = listOf(InternalFlags.ShouldSelectType)
)
val result = repo.createObject(command)
result.id
@ -64,7 +66,7 @@ class CreateDataViewObject(
relations = emptyList(),
type = type
),
internalFlags = listOf(InternalFlags.ShouldSelectTemplate)
internalFlags = listOf(InternalFlags.ShouldSelectType)
)
val result = repo.createObject(command)
result.id

View file

@ -820,18 +820,36 @@ class ObjectSetViewModel(
action: ((Id) -> Unit)? = null
) {
viewModelScope.launch {
createDataViewObject(params).process(
failure = { Timber.e(it, "Error while creating new record") },
success = { record ->
createDataViewObject.execute(params).fold(
onFailure = { Timber.e(it, "Error while creating new record") },
onSuccess = { newObject ->
proceedWithNewDataViewObject(params, newObject)
action?.invoke(newObject)
}
)
}
}
private suspend fun proceedWithNewDataViewObject(params: CreateDataViewObject.Params, newObject: Id) {
when (params) {
CreateDataViewObject.Params.Collection -> {
proceedWithOpeningObject(newObject)
}
is CreateDataViewObject.Params.SetByRelation -> {
proceedWithOpeningObject(newObject)
}
is CreateDataViewObject.Params.SetByType -> {
if (params.type == ObjectTypeIds.NOTE) {
proceedWithOpeningObject(newObject)
} else {
dispatch(
ObjectSetCommand.Modal.SetNameForCreatedObject(
ctx = context,
target = record
target = newObject
)
)
action?.invoke(record)
}
)
}
}
}

View file

@ -20,7 +20,7 @@ import com.anytypeio.anytype.presentation.sets.subscription.DefaultDataViewSubsc
import com.anytypeio.anytype.test_utils.MockDataFactory
import net.bytebuddy.utility.RandomString
class MockSet(context: String) {
class MockSet(context: String, setOfValue: String = "setOf-${RandomString.make()}") {
val root = context
val title =
@ -34,7 +34,8 @@ class MockSet(context: String) {
)
val workspaceId = "workspace-${RandomString.make()}"
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(context)
val setOf = "setOf-${RandomString.make()}"
val setOf = setOfValue
val setOfNote = ObjectTypeIds.NOTE
// RELATION OBJECTS
val relationObject1 = StubRelationObject(

View file

@ -0,0 +1,249 @@
package com.anytypeio.anytype.presentation.collections
import app.cash.turbine.testIn
import com.anytypeio.anytype.core_models.ObjectTypeIds
import com.anytypeio.anytype.domain.base.Resultat
import com.anytypeio.anytype.domain.dataview.interactor.CreateDataViewObject
import com.anytypeio.anytype.presentation.sets.ObjectSetCommand
import com.anytypeio.anytype.presentation.sets.ObjectSetViewModel
import com.anytypeio.anytype.presentation.sets.main.ObjectSetViewModelTestSetup
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.doReturn
import org.mockito.kotlin.times
import org.mockito.kotlin.verifyBlocking
import org.mockito.kotlin.verifyNoInteractions
@OptIn(ExperimentalCoroutinesApi::class)
class ObjectCreateTest : ObjectSetViewModelTestSetup() {
private lateinit var viewModel: ObjectSetViewModel
private lateinit var mockObjectSet: MockSet
@Before
fun setup() {
MockitoAnnotations.openMocks(this)
viewModel = givenViewModel()
}
@After
fun after() {
rule.advanceTime()
}
@Test
fun `Should create and open Note Object when clicking on New button in Set By Type`() = runTest {
mockObjectSet = MockSet(context = root, setOfValue = ObjectTypeIds.NOTE)
// SETUP
stubWorkspaceManager(mockObjectSet.workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(mockObjectSet.header, mockObjectSet.title, mockObjectSet.dataView),
details = mockObjectSet.details
)
stubSubscriptionResults(
subscription = mockObjectSet.subscriptionId,
workspace = mockObjectSet.workspaceId,
storeOfRelations = storeOfRelations,
keys = mockObjectSet.dvKeys,
sources = listOf(mockObjectSet.setOf),
dvFilters = mockObjectSet.filters,
objects = listOf(mockObjectSet.obj1, mockObjectSet.obj2)
)
val newObjectId = "objNewNote-${RandomString.make()}"
doReturn(Resultat.success(newObjectId)).`when`(createDataViewObject).execute(
CreateDataViewObject.Params.SetByType(
type = ObjectTypeIds.NOTE,
filters = mockObjectSet.filters
)
)
doReturn(Resultat.success(Unit)).`when`(closeBlock).execute(mockObjectSet.root)
// TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
viewModel.onCreateNewDataViewObject()
advanceUntilIdle()
verifyBlocking(createDataViewObject, times(1)) {
execute(
CreateDataViewObject.Params.SetByType(
type = ObjectTypeIds.NOTE,
filters = mockObjectSet.filters
)
)
}
verifyBlocking(closeBlock, times(1)) { execute(mockObjectSet.root)}
}
@Test
fun `Should create and Set Name for Not-Note Object when clicking on New button in Set by Type`() = runTest {
mockObjectSet = MockSet(context = root, setOfValue = ObjectTypeIds.PAGE)
// SETUP
stubWorkspaceManager(mockObjectSet.workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(mockObjectSet.header, mockObjectSet.title, mockObjectSet.dataView),
details = mockObjectSet.details
)
stubSubscriptionResults(
subscription = mockObjectSet.subscriptionId,
workspace = mockObjectSet.workspaceId,
storeOfRelations = storeOfRelations,
keys = mockObjectSet.dvKeys,
sources = listOf(mockObjectSet.setOf),
dvFilters = mockObjectSet.filters,
objects = listOf(mockObjectSet.obj1, mockObjectSet.obj2)
)
val newObjectId = "objNewPage-${RandomString.make()}"
doReturn(Resultat.success(newObjectId)).`when`(createDataViewObject).execute(
CreateDataViewObject.Params.SetByType(
type = ObjectTypeIds.PAGE,
filters = mockObjectSet.filters
)
)
doReturn(Resultat.success(Unit)).`when`(closeBlock).execute(mockObjectSet.root)
// TESTING
viewModel.onStart(ctx = root)
val commandFlow = viewModel.commands.testIn(backgroundScope)
advanceUntilIdle()
viewModel.onCreateNewDataViewObject()
assertIs<ObjectSetCommand.Modal.SetNameForCreatedObject>(commandFlow.awaitItem())
advanceUntilIdle()
verifyBlocking(createDataViewObject, times(1)) {
execute(
CreateDataViewObject.Params.SetByType(
type = ObjectTypeIds.PAGE,
filters = mockObjectSet.filters
)
)
}
verifyNoInteractions(closeBlock)
}
@Test
fun `Should create and open Object when clicking on New button in Set by Relations`() = runTest {
mockObjectSet = MockSet(context = root, setOfValue = ObjectTypeIds.NOTE)
// SETUP
stubWorkspaceManager(mockObjectSet.workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(mockObjectSet.header, mockObjectSet.title, mockObjectSet.dataView),
details = mockObjectSet.detailsSetByRelation
)
stubSubscriptionResults(
subscription = mockObjectSet.subscriptionId,
workspace = mockObjectSet.workspaceId,
storeOfRelations = storeOfRelations,
keys = mockObjectSet.dvKeys,
sources = listOf(mockObjectSet.setOf),
dvFilters = mockObjectSet.filters,
objects = listOf(mockObjectSet.obj1, mockObjectSet.obj2)
)
val newObjectId = "objNew-${RandomString.make()}"
doReturn(Resultat.success(newObjectId)).`when`(createDataViewObject).execute(
CreateDataViewObject.Params.SetByRelation(
relations = listOf(mockObjectSet.relationObject3.id),
filters = mockObjectSet.filters
)
)
doReturn(Resultat.success(Unit)).`when`(closeBlock).execute(mockObjectSet.root)
// TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
viewModel.onCreateNewDataViewObject()
advanceUntilIdle()
verifyBlocking(createDataViewObject, times(1)) {
execute(
CreateDataViewObject.Params.SetByRelation(
relations = listOf(mockObjectSet.relationObject3.id),
filters = mockObjectSet.filters
)
)
}
verifyBlocking(closeBlock, times(1)) { execute(mockObjectSet.root)}
}
@Test
fun `Should create and open Object when clicking on New button in Collection`() = runTest {
val objectCollection = MockCollection(context = root)
// SETUP
stubWorkspaceManager(objectCollection.workspaceId)
stubStoreOfRelations(objectCollection)
stubSubscriptionResults(
subscription = objectCollection.subscriptionId,
collection = root,
workspace = objectCollection.workspaceId,
storeOfRelations = storeOfRelations,
keys = objectCollection.dvKeys,
objects = listOf(objectCollection.obj1, objectCollection.obj2),
dvSorts = objectCollection.sorts
)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(
objectCollection.header,
objectCollection.title,
objectCollection.dataView
),
details = objectCollection.details
)
val newObjectId = "objNew-${RandomString.make()}"
doReturn(Resultat.success(newObjectId)).`when`(createDataViewObject).execute(
CreateDataViewObject.Params.Collection
)
doReturn(Resultat.success(Unit)).`when`(closeBlock).execute(objectCollection.root)
// TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
viewModel.onCreateNewDataViewObject()
advanceUntilIdle()
verifyBlocking(createDataViewObject, times(1)) {
execute(CreateDataViewObject.Params.Collection)
}
verifyBlocking(closeBlock, times(1)) { execute(objectCollection.root)}
}
}

View file

@ -54,7 +54,7 @@ class ObjectSetDataViewObjectCreateTest : ObjectSetViewModelTestSetup() {
dvFilters = mockObjectSet.filters,
objects = listOf(mockObjectSet.obj1, mockObjectSet.obj2)
)
doReturn(Unit).`when`(createDataViewObject).invoke(
doReturn(Unit).`when`(createDataViewObject).execute(
CreateDataViewObject.Params.SetByType(
type = mockObjectSet.setOf,
filters = mockObjectSet.filters
@ -79,7 +79,7 @@ class ObjectSetDataViewObjectCreateTest : ObjectSetViewModelTestSetup() {
advanceUntilIdle()
verifyBlocking(createDataViewObject, times(1)) {
invoke(
execute(
CreateDataViewObject.Params.SetByType(
type = mockObjectSet.setOf,
filters = mockObjectSet.filters

View file

@ -1,5 +1,6 @@
package com.anytypeio.anytype.presentation.sets.main
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.anytypeio.anytype.analytics.base.Analytics
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.Event
@ -79,6 +80,9 @@ open class ObjectSetViewModelTestSetup {
@get:Rule
val rule = DefaultCoroutineTestRule()
@get:Rule
val instantExecutorRule = InstantTaskExecutorRule()
@Mock
lateinit var openObjectSet: OpenObjectSet

View file

@ -58,7 +58,7 @@ class SetByRelationTest : ObjectSetViewModelTestSetup() {
objects = listOf(mockObjectSet.obj1, mockObjectSet.obj2),
dvFilters = mockObjectSet.filters
)
doReturn(Unit).`when`(createDataViewObject).invoke(
doReturn(Unit).`when`(createDataViewObject).execute(
CreateDataViewObject.Params.SetByType(
type = mockObjectSet.setOf,
filters = mockObjectSet.filters
@ -83,7 +83,7 @@ class SetByRelationTest : ObjectSetViewModelTestSetup() {
advanceUntilIdle()
verifyBlocking(createDataViewObject, times(1)) {
invoke(
execute(
CreateDataViewObject.Params.SetByType(
type = mockObjectSet.setOf,
filters = mockObjectSet.filters
@ -114,7 +114,7 @@ class SetByRelationTest : ObjectSetViewModelTestSetup() {
objects = listOf(mockObjectSet.obj1, mockObjectSet.obj2),
dvFilters = mockObjectSet.filters
)
doReturn(Unit).`when`(createDataViewObject).invoke(
doReturn(Unit).`when`(createDataViewObject).execute(
CreateDataViewObject.Params.SetByRelation(
relations = listOf(mockObjectSet.relationObject3.id),
filters = mockObjectSet.filters
@ -139,7 +139,7 @@ class SetByRelationTest : ObjectSetViewModelTestSetup() {
advanceUntilIdle()
verifyBlocking(createDataViewObject, times(1)) {
invoke(
execute(
CreateDataViewObject.Params.SetByRelation(
relations = listOf(mockObjectSet.relationObject3.id),
filters = mockObjectSet.filters