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

DROID-1715 Set | Enhancment | View default object type and templates (#373)

# Conflicts:
#	core-ui/src/main/java/com/anytypeio/anytype/core_ui/widgets/ObjectTypeTemplatesWidget.kt
#	presentation/src/main/java/com/anytypeio/anytype/presentation/sets/ObjectSetExtension.kt
#	presentation/src/main/java/com/anytypeio/anytype/presentation/sets/ObjectSetViewModel.kt
This commit is contained in:
Konstantin Ivanov 2023-09-13 18:50:04 +02:00 committed by konstantiniiv
parent 1652dc1b4c
commit a528fb09a8
12 changed files with 2392 additions and 204 deletions

View file

@ -83,6 +83,8 @@ import com.anytypeio.anytype.presentation.editor.cover.CoverColor
import com.anytypeio.anytype.presentation.editor.cover.CoverGradient
import com.anytypeio.anytype.presentation.templates.TemplateMenuClick
import com.anytypeio.anytype.presentation.templates.TemplateView
import com.anytypeio.anytype.presentation.templates.TemplateView.Companion.DEFAULT_TEMPLATE_ID_BLANK
import com.anytypeio.anytype.presentation.templates.TemplateView.Companion.DEFAULT_TEMPLATE_ID_BLANK
import com.anytypeio.anytype.presentation.widgets.TemplatesWidgetUiState
import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope
@ -813,7 +815,7 @@ enum class DragStates {
fun ComposablePreview() {
val items = listOf(
TemplateView.Blank(
id = TemplateView.DEFAULT_TEMPLATE_ID_BLANK,
id = DEFAULT_TEMPLATE_ID_BLANK,
typeId = "page",
typeName = "Page",
layout = ObjectType.Layout.BASIC.code

View file

@ -23,7 +23,6 @@ import com.anytypeio.anytype.core_utils.ext.addAfterIndexInLine
import com.anytypeio.anytype.core_utils.ext.mapInPlace
import com.anytypeio.anytype.core_utils.ext.moveAfterIndexInLine
import com.anytypeio.anytype.core_utils.ext.moveOnTop
import com.anytypeio.anytype.domain.launch.GetDefaultPageType
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.domain.objects.StoreOfRelations
@ -49,6 +48,7 @@ import com.anytypeio.anytype.presentation.sets.state.ObjectState.Companion.VIEW_
import com.anytypeio.anytype.presentation.sets.viewer.ViewerView
import com.anytypeio.anytype.presentation.templates.TemplateView
import com.anytypeio.anytype.presentation.templates.TemplateView.Companion.DEFAULT_TEMPLATE_ID_BLANK
import timber.log.Timber
fun ObjectState.DataView.featuredRelations(
ctx: Id,
@ -399,16 +399,6 @@ fun ObjectState.DataView.Set.isSetByRelation(setOfValue: List<Id>): Boolean {
return objectDetails.type == ObjectTypeIds.RELATION
}
suspend fun StoreOfObjectTypes.isTemplatesAllowedForDefaultType(getDefaultPageType: GetDefaultPageType): Boolean {
try {
val defaultObjectType = getDefaultPageType.run(Unit).type ?: return false
val defaultObjType = get(defaultObjectType) ?: return false
return defaultObjType.isTemplatesAllowed()
} catch (e: Exception) {
return false
}
}
private fun ObjectState.DataView.isValidObject(objectId: Id): Boolean {
val objectDetails = details[objectId] ?: return false
val objectWrapper = ObjectWrapper.Basic(objectDetails.map)
@ -437,11 +427,10 @@ fun Viewer.isEmpty(): Boolean =
}
fun ObjectWrapper.Basic.toTemplateView(
typeId: Id,
urlBuilder: UrlBuilder,
coverImageHashProvider: CoverImageHashProvider,
objectTypeDefaultTemplate: Id? = null,
viewerDefaultTemplate: Id? = null
viewerDefObjType: ObjectWrapper.Type,
viewerDefTemplateId: Id?,
): TemplateView.Template {
val coverContainer = if (coverType != CoverType.NONE) {
BasicObjectCoverWrapper(this)
@ -449,33 +438,28 @@ fun ObjectWrapper.Basic.toTemplateView(
} else {
null
}
val isDefault = if (viewerDefaultTemplate != null) {
viewerDefaultTemplate == id
} else {
false
}
return TemplateView.Template(
id = id,
name = name.orEmpty(),
typeId = typeId,
typeId = viewerDefObjType.id,
emoji = if (!iconEmoji.isNullOrBlank()) iconEmoji else null,
image = if (!iconImage.isNullOrBlank()) urlBuilder.thumbnail(iconImage!!) else null,
layout = layout ?: ObjectType.Layout.BASIC,
coverColor = coverContainer?.coverColor,
coverImage = coverContainer?.coverImage,
coverGradient = coverContainer?.coverGradient,
isDefault = isDefault
isDefault = viewerDefTemplateId == id
)
}
fun ObjectWrapper.Type.toTemplateViewBlank(
viewerDefaultTemplate: Id? = null
viewerDefaultTemplate: Id?
): TemplateView.Blank {
return TemplateView.Blank(
id = DEFAULT_TEMPLATE_ID_BLANK,
typeId = id,
layout = recommendedLayout?.code ?: ObjectType.Layout.BASIC.code,
isDefault = viewerDefaultTemplate == DEFAULT_TEMPLATE_ID_BLANK
isDefault = viewerDefaultTemplate.isNullOrEmpty() || viewerDefaultTemplate == DEFAULT_TEMPLATE_ID_BLANK
)
}
@ -546,43 +530,70 @@ suspend fun List<ViewerView>.isActiveWithTemplates(storeOfObjectTypes: StoreOfOb
return viewerDefaultObjectType.isTemplatesAllowed()
}
fun ObjectState.DataView.Collection.getDefaultObjectTypeForCollection(viewer: DVViewer?): Id {
return viewer?.defaultObjectType ?: VIEW_DEFAULT_OBJECT_TYPE
}
fun ObjectState.DataView.Set.getDefaultObjectTypeForSet(ctx: Id, viewer: DVViewer?): Id? {
val setOfValue = getSetOfValue(ctx)
return if (isSetByRelation(setOfValue = setOfValue)) {
viewer?.defaultObjectType ?: VIEW_DEFAULT_OBJECT_TYPE
} else {
setOfValue.firstOrNull()
}
}
fun ObjectState.DataView.getDefaultObjectType(ctx: Id, viewer: DVViewer?): Id? {
return when (this) {
is ObjectState.DataView.Collection -> getDefaultObjectTypeForCollection(viewer)
is ObjectState.DataView.Set -> getDefaultObjectTypeForSet(ctx, viewer)
}
}
//TODO Refact
suspend fun DVViewer.getProperTemplateId(
templateId: Id?,
storeOfObjectTypes: StoreOfObjectTypes
): Id? {
return if (templateId != null) {
if (templateId == DEFAULT_TEMPLATE_ID_BLANK) {
null
val defaultObjectTypeId = defaultObjectType
return if (defaultObjectTypeId != null) {
if (defaultTemplate != null) {
defaultTemplate
} else {
templateId
storeOfObjectTypes.get(defaultObjectTypeId)?.defaultTemplateId
}
} else {
val defaultObjectTypeId = defaultObjectType
if (defaultObjectTypeId != null) {
storeOfObjectTypes.get(defaultObjectTypeId)?.defaultTemplateId
} else {
null
null
}
}
suspend fun ObjectState.DataView.getActiveViewTypeAndTemplate(
ctx: Id,
activeView: DVViewer?,
storeOfObjectTypes: StoreOfObjectTypes
): Pair<ObjectWrapper.Type?, Id?> {
if (activeView == null) return Pair(null, null)
when (this) {
is ObjectState.DataView.Collection -> {
return resolveTypeAndActiveViewTemplate(activeView, storeOfObjectTypes)
}
is ObjectState.DataView.Set -> {
val setOfValue = getSetOfValue(ctx)
return if (isSetByRelation(setOfValue = setOfValue)) {
resolveTypeAndActiveViewTemplate(activeView, storeOfObjectTypes)
} else {
val setOf = setOfValue.firstOrNull()
if (setOf.isNullOrBlank()) {
Timber.d("Set by type setOf param is null or empty, not possible to get Type and Template")
Pair(null, null)
} else {
val defaultSetObjectType = ObjectWrapper.Type(details[setOf]?.map.orEmpty())
if (activeView.defaultTemplate.isNullOrEmpty()) {
val defaultTemplateId = defaultSetObjectType.defaultTemplateId
Pair(defaultSetObjectType, defaultTemplateId)
} else {
Pair(defaultSetObjectType, activeView.defaultTemplate)
}
}
}
}
}
}
}
private suspend fun resolveTypeAndActiveViewTemplate(
activeView: DVViewer,
storeOfObjectTypes: StoreOfObjectTypes
): Pair<ObjectWrapper.Type?, Id?> {
val activeViewDefaultObjectType = activeView.defaultObjectType
val defaultSetObjectTypId = if (!activeViewDefaultObjectType.isNullOrBlank()) {
activeViewDefaultObjectType
} else {
VIEW_DEFAULT_OBJECT_TYPE
}
val defaultSetObjectType = storeOfObjectTypes.get(defaultSetObjectTypId)
return if (activeView.defaultTemplate.isNullOrEmpty()) {
val defaultTemplateId = defaultSetObjectType?.defaultTemplateId
Pair(defaultSetObjectType, defaultTemplateId)
} else {
Pair(defaultSetObjectType, activeView.defaultTemplate)
}
}

View file

@ -490,7 +490,6 @@ class ObjectSetViewModel(
return when (dataViewState) {
DataViewState.Init -> {
_dvViews.value = emptyList()
viewerEditWidgetState.value = viewerEditWidgetState.value.empty()
if (dvViewer == null) {
DataViewViewState.Collection.NoView
} else {
@ -498,17 +497,7 @@ class ObjectSetViewModel(
}
}
is DataViewState.Loaded -> {
_dvViews.value = objectState.dataViewState()?.toViewersView(context, session, storeOfRelations) ?: emptyList()
viewerEditWidgetState.value = if (dvViewer != null) {
viewerEditWidgetState.value.updateState(
dvViewer = dvViewer,
isDefaultObjectTypeEnabled = true,
storeOfRelations = storeOfRelations,
storeOfObjectTypes = storeOfObjectTypes
)
} else {
viewerEditWidgetState.value.empty()
}
_dvViews.value = objectState.dataViewState()?.toViewersView(context, session) ?: emptyList()
val relations = objectState.dataViewContent.relationLinks.mapNotNull {
storeOfRelations.getByKey(it.key)
}
@ -517,14 +506,20 @@ class ObjectSetViewModel(
when {
viewer == null -> DataViewViewState.Collection.NoView
viewer.isEmpty() -> {
val hasTemplates = _dvViews.value.isActiveWithTemplates(storeOfObjectTypes)
val (defType, _) = objectState.getActiveViewTypeAndTemplate(
context, dvViewer, storeOfObjectTypes
)
val hasTemplates = defType?.isTemplatesAllowed() ?: false
DataViewViewState.Collection.NoItems(
title = viewer.title,
hasTemplates = hasTemplates
)
}
else -> {
val hasTemplates = _dvViews.value.isActiveWithTemplates(storeOfObjectTypes)
val (defType, _) = objectState.getActiveViewTypeAndTemplate(
context, dvViewer, storeOfObjectTypes
)
val hasTemplates = defType?.isTemplatesAllowed() ?: false
DataViewViewState.Collection.Default(
viewer = viewer,
hasTemplates = hasTemplates
@ -549,7 +544,6 @@ class ObjectSetViewModel(
return when (dataViewState) {
DataViewState.Init -> {
_dvViews.value = emptyList()
viewerEditWidgetState.value = viewerEditWidgetState.value.empty()
when {
setOfValue.isEmpty() || query.isEmpty() -> DataViewViewState.Set.NoQuery
viewer == null -> DataViewViewState.Set.NoView
@ -557,18 +551,7 @@ class ObjectSetViewModel(
}
}
is DataViewState.Loaded -> {
_dvViews.value = objectState.dataViewState()?.toViewersView(context, session, storeOfRelations) ?: emptyList()
viewerEditWidgetState.value = if (viewer != null) {
viewerEditWidgetState.value.updateState(
dvViewer = viewer,
isDefaultObjectTypeEnabled = objectState.isSetByRelation(setOfValue),
storeOfRelations = storeOfRelations,
storeOfObjectTypes = storeOfObjectTypes
)
} else {
viewerEditWidgetState.value.empty()
}
_dvViews.value = objectState.dataViewState()?.toViewersView(context, session) ?: emptyList()
val relations = objectState.dataViewContent.relationLinks.mapNotNull {
storeOfRelations.getByKey(it.key)
}
@ -585,15 +568,21 @@ class ObjectSetViewModel(
query.isEmpty() || setOfValue.isEmpty() -> DataViewViewState.Set.NoQuery
render == null -> DataViewViewState.Set.NoView
render.isEmpty() -> {
val (defType, _) = objectState.getActiveViewTypeAndTemplate(
context, viewer, storeOfObjectTypes
)
DataViewViewState.Set.NoItems(
title = render.title,
hasTemplates = _dvViews.value.isActiveWithTemplates(storeOfObjectTypes)
hasTemplates = defType?.isTemplatesAllowed() ?: false
)
}
else -> {
val (defType, _) = objectState.getActiveViewTypeAndTemplate(
context, viewer, storeOfObjectTypes
)
DataViewViewState.Set.Default(
viewer = render,
hasTemplates = _dvViews.value.isActiveWithTemplates(storeOfObjectTypes)
hasTemplates = defType?.isTemplatesAllowed() ?: false
)
}
}
@ -919,7 +908,7 @@ class ObjectSetViewModel(
}
}
private suspend fun proceedWithCreatingSetObject(currentState: ObjectState.DataView.Set, templateId: Id?) {
private suspend fun proceedWithCreatingSetObject(currentState: ObjectState.DataView.Set, templateChosenBy: Id?) {
if (isRestrictionPresent(DataViewRestriction.CREATE_OBJECT)) {
toast(NOT_ALLOWED)
} else {
@ -932,7 +921,8 @@ class ObjectSetViewModel(
return
}
val defaultObjectType = currentState.getDefaultObjectTypeForSet(ctx = context, viewer = viewer)
val (defaultObjectType, defaultTemplate)
= currentState.getActiveViewTypeAndTemplate(context, viewer, storeOfObjectTypes)
val sourceId = setObject.setOf.singleOrNull()
if (defaultObjectType == null) {
@ -942,12 +932,6 @@ class ObjectSetViewModel(
if (sourceDetails != null && sourceDetails.map.isNotEmpty()) {
when (sourceDetails.type.firstOrNull()) {
ObjectTypeIds.OBJECT_TYPE -> {
val createObjectTemplateId =
if (templateId == TemplateView.DEFAULT_TEMPLATE_ID_BLANK) {
null
} else {
templateId
}
if (sourceId == ObjectTypeIds.BOOKMARK) {
dispatch(
ObjectSetCommand.Modal.CreateBookmark(
@ -955,23 +939,30 @@ class ObjectSetViewModel(
)
)
} else {
val validTemplateId = getValidTemplateId(
templateChosenBy = templateChosenBy,
viewDefaultTemplate = defaultTemplate
)
proceedWithCreatingDataViewObject(
CreateDataViewObject.Params.SetByType(
type = defaultObjectType,
type = defaultObjectType.id,
filters = viewer.filters,
template = createObjectTemplateId
template = validTemplateId
)
)
}
}
ObjectTypeIds.RELATION -> {
val createObjectTemplateId = viewer.getProperTemplateId(templateId, storeOfObjectTypes)
val validTemplateId = getValidTemplateId(
templateChosenBy = templateChosenBy,
viewDefaultTemplate = defaultTemplate
)
proceedWithCreatingDataViewObject(
CreateDataViewObject.Params.SetByRelation(
filters = viewer.filters,
relations = setObject.setOf,
template = createObjectTemplateId,
type = defaultObjectType
template = validTemplateId,
type = defaultObjectType.id
)
)
}
@ -983,18 +974,32 @@ class ObjectSetViewModel(
}
}
private fun getValidTemplateId(templateChosenBy: Id?, viewDefaultTemplate: Id?): Id? {
return when (templateChosenBy) {
null -> if (viewDefaultTemplate != TemplateView.DEFAULT_TEMPLATE_ID_BLANK) viewDefaultTemplate else null
TemplateView.DEFAULT_TEMPLATE_ID_BLANK -> null
else -> templateChosenBy
}
}
fun onSelectQueryButtonClicked() {
dispatch(ObjectSetCommand.Modal.OpenEmptyDataViewSelectQueryScreen)
}
private suspend fun proceedWithAddingObjectToCollection(templateId: Id? = null) {
private suspend fun proceedWithAddingObjectToCollection(templateChosenBy: Id? = null) {
val state = stateReducer.state.value.dataViewState() ?: return
val viewer = state.viewerById(session.currentViewerId.value) ?: return
val createObjectTemplateId = viewer.getProperTemplateId(templateId, storeOfObjectTypes)
val (defaultObjectType, defaultTemplate)
= state.getActiveViewTypeAndTemplate(context, viewer, storeOfObjectTypes)
val validTemplateId = getValidTemplateId(
templateChosenBy = templateChosenBy,
viewDefaultTemplate = defaultTemplate
)
val createObjectParams = CreateDataViewObject.Params.Collection(
templateId = createObjectTemplateId,
type = viewer.defaultObjectType
templateId = validTemplateId,
type = defaultObjectType?.id
)
proceedWithCreatingDataViewObject(createObjectParams) { result ->
val params = AddObjectToCollection.Params(
@ -1513,26 +1518,22 @@ class ObjectSetViewModel(
currentViewId
)
}.flatMapLatest { (state, currentViewId) ->
val viewer = state.dataViewState()?.viewerById(currentViewId)
val viewerDefObjType = fetchViewerDefaultObjectType(state, viewer)
if (viewer != null && viewerDefObjType?.isTemplatesAllowed() == true) {
fetchAndProcessTemplates(viewerDefObjType, viewer)
val viewer = state.dataViewState()?.viewerById(currentViewId) ?: return@flatMapLatest emptyFlow()
val (type, template) = state.getActiveViewTypeAndTemplate(context, viewer, storeOfObjectTypes)
if (type == null) return@flatMapLatest emptyFlow()
if (type.isTemplatesAllowed()) {
fetchAndProcessTemplates(type, template)
} else {
Timber.d("Templates are not allowed for type:[${viewerDefObjType?.id}]")
Timber.d("Templates are not allowed for type:[${type.id}]")
emptyFlow()
}
}.onEach { _templateViews.value = it }.collect()
}
}
private suspend fun fetchViewerDefaultObjectType(state: ObjectState.DataView, viewer: DVViewer?): ObjectWrapper.Type? {
val viewerDefaultObjectTypeId = state.getDefaultObjectType(ctx = context, viewer = viewer) ?: return null
return storeOfObjectTypes.get(viewerDefaultObjectTypeId)
}
private suspend fun fetchAndProcessTemplates(
viewerDefObjType: ObjectWrapper.Type,
viewer: DVViewer
viewerDefTemplateId: Id?,
): Flow<List<TemplateView>> {
Timber.d("Fetching templates for type ${viewerDefObjType.id}")
@ -1543,27 +1544,26 @@ class ObjectSetViewModel(
emptyFlow<List<TemplateView>>()
}
.map { results ->
processTemplates(results, viewerDefObjType, viewer)
processTemplates(results, viewerDefObjType, viewerDefTemplateId)
}
}
private fun processTemplates(
results: List<ObjectWrapper.Basic>,
viewerDefObjType: ObjectWrapper.Type,
viewer: DVViewer
viewerDefTemplateId: Id?
): List<TemplateView> {
val blankTemplate = listOf(
viewerDefObjType.toTemplateViewBlank(
viewerDefaultTemplate = viewer.defaultTemplate
viewerDefaultTemplate = viewerDefTemplateId
)
)
return blankTemplate + results.map { objTemplate ->
objTemplate.toTemplateView(
typeId = viewerDefObjType.id,
urlBuilder = urlBuilder,
coverImageHashProvider = coverImageHashProvider,
objectTypeDefaultTemplate = viewerDefObjType.defaultTemplateId,
viewerDefaultTemplate = viewer.defaultTemplate
viewerDefObjType = viewerDefObjType,
viewerDefTemplateId = viewerDefTemplateId,
)
}.sortedByDescending { it.isDefault } + listOf(TemplateView.New(viewerDefObjType.id))
}
@ -1587,7 +1587,7 @@ class ObjectSetViewModel(
}
viewModelScope.launch {
delay(DELAY_BEFORE_CREATING_TEMPLATE)
proceedWithDataViewObjectCreate(item.id)
proceedWithDataViewObjectCreate(templateId = null)
}
}
is TemplateView.Template -> {
@ -1954,10 +1954,10 @@ class ObjectSetViewModel(
viewModelScope.launch {
when (state) {
is ObjectState.DataView.Collection -> {
proceedWithAddingObjectToCollection(getCreateObjectTemplateId(templateId))
proceedWithAddingObjectToCollection(templateChosenBy = templateId)
}
is ObjectState.DataView.Set -> {
proceedWithCreatingSetObject(state, getCreateObjectTemplateId(templateId))
proceedWithCreatingSetObject(currentState = state, templateChosenBy = templateId)
}
}
}

View file

@ -1,14 +1,18 @@
package com.anytypeio.anytype.presentation.collections
import app.cash.turbine.testIn
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.ObjectTypeIds
import com.anytypeio.anytype.core_models.Relation
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.StubRelationObject
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 com.anytypeio.anytype.presentation.sets.state.ObjectState
import com.anytypeio.anytype.test_utils.MockDataFactory
import kotlin.test.assertIs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.advanceUntilIdle
@ -18,6 +22,7 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.times
import org.mockito.kotlin.verifyBlocking
@ -171,6 +176,17 @@ class ObjectCreateTest : ObjectSetViewModelTestSetup() {
isReadOnlyValue = false,
format = Relation.Format.LONG_TEXT
)
val pageTypeId = ObjectState.VIEW_DEFAULT_OBJECT_TYPE
val pageTypeMap = mapOf(
Relations.ID to pageTypeId,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.BASIC.code.toDouble(),
Relations.NAME to MockDataFactory.randomString(),
Relations.DEFAULT_TEMPLATE_ID to null
)
with(storeOfObjectTypes) {
set(pageTypeId, pageTypeMap)
}
// SETUP
stubWorkspaceManager(mockObjectSet.workspaceId)
@ -258,6 +274,18 @@ class ObjectCreateTest : ObjectSetViewModelTestSetup() {
details = objectCollection.details
)
val pageTypeId = ObjectState.VIEW_DEFAULT_OBJECT_TYPE
val pageTypeMap = mapOf(
Relations.ID to pageTypeId,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.BASIC.code.toDouble(),
Relations.NAME to MockDataFactory.randomString(),
Relations.DEFAULT_TEMPLATE_ID to null
)
with(storeOfObjectTypes) {
set(pageTypeId, pageTypeMap)
}
val newObjectId = "objNew-${RandomString.make()}"
val result = CreateDataViewObject.Result(
objectId = newObjectId,

View file

@ -99,8 +99,7 @@ class ObjectSetReducerTest {
type = Block.Content.DataView.Sort.Type.DESC
)
),
filters = listOf(),
defaultObjectType = ObjectTypeIds.PAGE
filters = listOf()
)
val dataView = Block(
@ -228,8 +227,7 @@ class ObjectSetReducerTest {
type = Block.Content.DataView.Sort.Type.ASC
)
),
filters = listOf(),
defaultObjectType = ObjectTypeIds.PAGE
filters = listOf()
)
val viewerList = Block.Content.DataView.Viewer(
@ -276,8 +274,7 @@ class ObjectSetReducerTest {
)
),
filters = listOf(),
viewerRelations = viewerGrid.viewerRelations,
defaultObjectType = ObjectTypeIds.PAGE
viewerRelations = viewerGrid.viewerRelations
)
)
@ -299,8 +296,7 @@ class ObjectSetReducerTest {
type = viewerGrid.type,
viewerRelations = viewerGrid.viewerRelations,
sorts = viewerGrid.sorts,
filters = viewerGrid.filters,
defaultObjectType = ObjectTypeIds.PAGE
filters = viewerGrid.filters
),
Block.Content.DataView.Viewer(
id = viewerList.id,
@ -313,8 +309,7 @@ class ObjectSetReducerTest {
type = Block.Content.DataView.Sort.Type.DESC
)
),
filters = listOf(),
defaultObjectType = ObjectTypeIds.PAGE
filters = listOf()
)
)
),
@ -439,8 +434,7 @@ class ObjectSetReducerTest {
type = viewer1.type,
viewerRelations = viewer1.viewerRelations,
sorts = expectedSorts,
filters = viewer1.filters,
defaultObjectType = ObjectTypeIds.PAGE
filters = viewer1.filters
),
Block.Content.DataView.Viewer(
id = viewer2.id,
@ -448,8 +442,7 @@ class ObjectSetReducerTest {
type = Block.Content.DataView.Viewer.Type.GRID,
viewerRelations = viewer2.viewerRelations,
sorts = listOf(sort1),
filters = listOf(),
defaultObjectType = ObjectTypeIds.PAGE
filters = listOf()
)
),
targetObjectId = (dataView.content as Block.Content.DataView).targetObjectId
@ -561,8 +554,7 @@ class ObjectSetReducerTest {
type = viewer1.type,
viewerRelations = viewer1.viewerRelations,
sorts = viewer1.sorts,
filters = expectedFilters,
defaultObjectType = ObjectTypeIds.PAGE
filters = expectedFilters
)
),
targetObjectId = (dataView.content as Block.Content.DataView).targetObjectId
@ -669,8 +661,7 @@ class ObjectSetReducerTest {
type = viewer1.type,
viewerRelations = expectedRelations,
sorts = viewer1.sorts,
filters = viewer1.filters,
defaultObjectType = ObjectTypeIds.PAGE
filters = viewer1.filters
)
),
targetObjectId = (dataView.content as Block.Content.DataView).targetObjectId
@ -769,8 +760,7 @@ class ObjectSetReducerTest {
name = newViewerName,
cardSize = newCardSize,
coverFit = newCoverFit,
coverRelationKey = relationKey1,
defaultObjectType = ObjectTypeIds.PAGE
coverRelationKey = relationKey1
)
),
targetObjectId = (dataView.content as Block.Content.DataView).targetObjectId
@ -848,8 +838,7 @@ class ObjectSetReducerTest {
sorts = viewer.sorts,
filters = viewer.filters,
name = viewer.name,
coverRelationKey = viewer.coverRelationKey,
defaultObjectType = ObjectTypeIds.PAGE
coverRelationKey = viewer.coverRelationKey
)
),
relationLinks = listOf(relationLink1, relationLink3),

View file

@ -15,6 +15,7 @@ import com.anytypeio.anytype.core_models.restrictions.DataViewRestrictions
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
import com.anytypeio.anytype.domain.base.Either
import com.anytypeio.anytype.domain.base.Result
import com.anytypeio.anytype.domain.base.Resultat
import com.anytypeio.anytype.domain.block.interactor.UpdateText
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.collections.AddObjectToCollection
@ -390,4 +391,20 @@ open class ObjectSetViewModelTestSetup {
onBlocking { subscribe(type) }.thenReturn(flowOf(templates))
}
}
fun stubCreateDataViewObject(
objectId: Id = MockDataFactory.randomString(),
objectType: Id = MockDataFactory.randomString()
) {
createDataViewObject.stub {
onBlocking { async(any()) }.thenReturn(
Resultat.success(
CreateDataViewObject.Result(
objectId = objectId,
objectType = objectType
)
)
)
}
}
}

View file

@ -91,60 +91,4 @@ class SetByRelationTest : ObjectSetViewModelTestSetup() {
}
}
}
@Test
fun `should create new object with default object type if given set is aggregated by relations`() = runTest {
// SETUP
stubWorkspaceManager(mockObjectSet.workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubStoreOfRelations(mockObjectSet)
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.relationObject3.id),
objects = listOf(mockObjectSet.obj1, mockObjectSet.obj2),
dvFilters = mockObjectSet.filters
)
doReturn(Unit).`when`(createDataViewObject).async(
CreateDataViewObject.Params.SetByRelation(
relations = listOf(mockObjectSet.relationObject3.id),
filters = mockObjectSet.filters,
template = null,
type = ObjectTypeIds.PAGE
)
)
// TESTING
viewModel.onStart(ctx = root)
// ASSERT DATA VIEW STATE
viewModel.currentViewer.test {
val first = awaitItem()
assertIs<DataViewViewState.Init>(first)
val second = awaitItem()
assertIs<DataViewViewState.Set.Default>(second)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
verifyBlocking(createDataViewObject, times(1)) {
async(
CreateDataViewObject.Params.SetByRelation(
relations = listOf(mockObjectSet.relationObject3.id),
filters = mockObjectSet.filters,
template = null,
type = ObjectTypeIds.PAGE
)
)
}
}
}
}

View file

@ -0,0 +1,652 @@
package com.anytypeio.anytype.presentation.templates
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.ObjectTypeIds
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.StubDataView
import com.anytypeio.anytype.core_models.StubDataViewView
import com.anytypeio.anytype.core_models.StubDataViewViewRelation
import com.anytypeio.anytype.core_models.StubObject
import com.anytypeio.anytype.core_models.StubRelationLink
import com.anytypeio.anytype.core_models.StubRelationObject
import com.anytypeio.anytype.domain.dataview.interactor.CreateDataViewObject
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.state.ObjectState
import com.anytypeio.anytype.presentation.sets.subscription.DefaultDataViewSubscription
import com.anytypeio.anytype.test_utils.MockDataFactory
import kotlin.test.assertEquals
import kotlin.test.assertTrue
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.times
import org.mockito.kotlin.verifyBlocking
@OptIn(ExperimentalCoroutinesApi::class)
class CollectionViewerTypeAndTemplateTest: ObjectSetViewModelTestSetup() {
private lateinit var viewModel: ObjectSetViewModel
private lateinit var closable: AutoCloseable
val pageTypeId = ObjectState.VIEW_DEFAULT_OBJECT_TYPE
val pageTemplate1 = StubObject(
id = "pagetemplate1-${RandomString.make()}",
objectType = ObjectTypeIds.TEMPLATE,
targetObjectType = pageTypeId
)
val pageTemplate2 = StubObject(
id = "pagetemplate2-${RandomString.make()}",
objectType = ObjectTypeIds.TEMPLATE,
targetObjectType = pageTypeId
)
val customType1Id = "customType1-${RandomString.make()}"
val template1 = StubObject(
id = "template1-${RandomString.make()}",
objectType = ObjectTypeIds.TEMPLATE,
targetObjectType = customType1Id
)
val template2 = StubObject(
id = "template2-${RandomString.make()}",
objectType = ObjectTypeIds.TEMPLATE,
targetObjectType = customType1Id
)
val collectionObjDetails = mapOf(
Relations.ID to root,
Relations.LAYOUT to ObjectType.Layout.COLLECTION.code.toDouble(),
)
@Before
fun setup() {
closable = MockitoAnnotations.openMocks(this)
viewModel = givenViewModel()
}
@After
fun after() {
rule.advanceTime()
closable.close()
}
/**
* Collection
* View default type : empty
* View default template : empty
* PAGE type default template : empty
*/
@Test
fun `set by relation, view type and template are empty, page template empty`() = runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = null,
defaultTemplateId = null
)
val dv = StubDataView(
views = listOf(viewer),
relationLinks = listOf(relationLink1),
isCollection = true
)
val dvKeys = listOf(relationObject1.key)
val pageTypeMap = mapOf(
Relations.ID to pageTypeId,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.BASIC.code.toDouble(),
Relations.NAME to MockDataFactory.randomString(),
Relations.DEFAULT_TEMPLATE_ID to null
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = collectionObjDetails),
pageTypeId to Block.Fields(map = pageTypeMap)
)
)
with(storeOfObjectTypes) {
set(pageTypeId, pageTypeMap)
}
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv), details = details
)
stubTemplatesContainer(
type = pageTypeId, templates = listOf(pageTemplate1, pageTemplate2)
)
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
objects = listOf(),
collection = root
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT BLANK IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Blank)
val uiState = viewModel.currentViewer.value as DataViewViewState.Collection.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.Collection(
type = pageTypeId,
templateId = null
)
async(params)
}
}
/**
* Collection
* View default type : empty
* View default template : empty
* PAGE type default template : blank
*/
@Test
fun `set by relation, view type and template are empty, page template blank`() = runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = null,
defaultTemplateId = null
)
val dv = StubDataView(
views = listOf(viewer),
relationLinks = listOf(relationLink1),
isCollection = true
)
val dvKeys = listOf(relationObject1.key)
val pageTypeMap = mapOf(
Relations.ID to pageTypeId,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.BASIC.code.toDouble(),
Relations.NAME to MockDataFactory.randomString(),
Relations.DEFAULT_TEMPLATE_ID to TemplateView.DEFAULT_TEMPLATE_ID_BLANK
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = collectionObjDetails),
pageTypeId to Block.Fields(map = pageTypeMap)
)
)
with(storeOfObjectTypes) {
set(pageTypeId, pageTypeMap)
}
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv), details = details
)
stubTemplatesContainer(
type = pageTypeId, templates = listOf(pageTemplate1, pageTemplate2)
)
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
objects = listOf(),
collection = root
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT BLANK IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Blank)
val uiState = viewModel.currentViewer.value as DataViewViewState.Collection.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.Collection(
type = pageTypeId,
templateId = null
)
async(params)
}
}
/**
* Collection
* View default type : empty
* View default template : empty
* PAGE type default template : Custom
*/
@Test
fun `set by relation, view type and template are empty, page template custom`() = runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = null,
defaultTemplateId = null
)
val dv = StubDataView(
views = listOf(viewer),
relationLinks = listOf(relationLink1),
isCollection = true
)
val dvKeys = listOf(relationObject1.key)
val pageTypeMap = mapOf(
Relations.ID to pageTypeId,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.BASIC.code.toDouble(),
Relations.NAME to MockDataFactory.randomString(),
Relations.DEFAULT_TEMPLATE_ID to pageTemplate2.id
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = collectionObjDetails),
pageTypeId to Block.Fields(map = pageTypeMap)
)
)
with(storeOfObjectTypes) {
set(pageTypeId, pageTypeMap)
}
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv), details = details
)
stubTemplatesContainer(
type = pageTypeId, templates = listOf(pageTemplate1, pageTemplate2)
)
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
objects = listOf(),
collection = root
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT BLANK IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Template)
val uiState = viewModel.currentViewer.value as DataViewViewState.Collection.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.Collection(
type = pageTypeId,
templateId = pageTemplate2.id
)
async(params)
}
}
/**
* Collection
* View default type : Type1
* View default template : empty
* CUSTOM type default template : Template1
*/
@Test
fun `set by relation, view type custom and template is empty`() = runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = customType1Id,
defaultTemplateId = null
)
val dv = StubDataView(
views = listOf(viewer),
relationLinks = listOf(relationLink1),
isCollection = true
)
val dvKeys = listOf(relationObject1.key)
val customType1Map = mapOf(
Relations.ID to customType1Id,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.TODO.code.toDouble(),
Relations.NAME to "name-$customType1Id",
Relations.DEFAULT_TEMPLATE_ID to template1.id
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = collectionObjDetails),
customType1Id to Block.Fields(map = customType1Map)
)
)
with(storeOfObjectTypes) {
set(customType1Id, customType1Map)
}
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv), details = details
)
stubTemplatesContainer(
type = customType1Id, templates = listOf(template2, template1)
)
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
objects = listOf(),
collection = root
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT BLANK IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Template)
val uiState = viewModel.currentViewer.value as DataViewViewState.Collection.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.Collection(
type = customType1Id,
templateId = template1.id
)
async(params)
}
}
/**
* Collection
* View default type : Type1
* View default template : blank
* CUSTOM type default template : Template1
*/
@Test
fun `set by relation, view type is custom and template is blank`() = runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = customType1Id,
defaultTemplateId = TemplateView.DEFAULT_TEMPLATE_ID_BLANK
)
val dv = StubDataView(
views = listOf(viewer),
relationLinks = listOf(relationLink1),
isCollection = true
)
val dvKeys = listOf(relationObject1.key)
val customType1Map = mapOf(
Relations.ID to customType1Id,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.TODO.code.toDouble(),
Relations.NAME to "name-$customType1Id",
Relations.DEFAULT_TEMPLATE_ID to template1.id
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = collectionObjDetails),
customType1Id to Block.Fields(map = customType1Map)
)
)
with(storeOfObjectTypes) {
set(customType1Id, customType1Map)
}
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv), details = details
)
stubTemplatesContainer(
type = customType1Id, templates = listOf(template2, template1)
)
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
objects = listOf(),
collection = root
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT BLANK IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Blank)
val uiState = viewModel.currentViewer.value as DataViewViewState.Collection.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.Collection(
type = customType1Id,
templateId = null
)
async(params)
}
}
/**
* Collection
* View default type : Type1
* View default template : Template2
* CUSTOM type default template : Template1
*/
@Test
fun `set by relation, view type is custom and template is not empty`() = runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = customType1Id,
defaultTemplateId = template2.id
)
val dv = StubDataView(
views = listOf(viewer),
relationLinks = listOf(relationLink1),
isCollection = true
)
val dvKeys = listOf(relationObject1.key)
val customType1Map = mapOf(
Relations.ID to customType1Id,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.TODO.code.toDouble(),
Relations.NAME to "name-$customType1Id",
Relations.DEFAULT_TEMPLATE_ID to template1.id
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = collectionObjDetails),
customType1Id to Block.Fields(map = customType1Map)
)
)
with(storeOfObjectTypes) {
set(customType1Id, customType1Map)
}
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv), details = details
)
stubTemplatesContainer(
type = customType1Id, templates = listOf(template2, template1)
)
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
objects = listOf(),
collection = root
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT BLANK IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Template)
val uiState = viewModel.currentViewer.value as DataViewViewState.Collection.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.Collection(
type = customType1Id,
templateId = template2.id
)
async(params)
}
}
}

View file

@ -0,0 +1,902 @@
package com.anytypeio.anytype.presentation.templates
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.ObjectTypeIds
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.StubDataView
import com.anytypeio.anytype.core_models.StubDataViewView
import com.anytypeio.anytype.core_models.StubDataViewViewRelation
import com.anytypeio.anytype.core_models.StubObject
import com.anytypeio.anytype.core_models.StubRelationLink
import com.anytypeio.anytype.core_models.StubRelationObject
import com.anytypeio.anytype.domain.dataview.interactor.CreateDataViewObject
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.state.ObjectState
import com.anytypeio.anytype.presentation.sets.subscription.DefaultDataViewSubscription
import com.anytypeio.anytype.presentation.templates.TemplateView.Companion.DEFAULT_TEMPLATE_ID_BLANK
import com.anytypeio.anytype.test_utils.MockDataFactory
import kotlin.test.assertEquals
import kotlin.test.assertTrue
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.times
import org.mockito.kotlin.verifyBlocking
@OptIn(ExperimentalCoroutinesApi::class)
class SetByRelationViewerTypeAndTemplateTest : ObjectSetViewModelTestSetup() {
private lateinit var viewModel: ObjectSetViewModel
private lateinit var closable: AutoCloseable
private val setByRelationId = "setByRelationId-${RandomString.make()}"
private val setByRelationKey = "setByRelationKey-${RandomString.make()}"
val setByRelationMap = mapOf(
Relations.ID to setByRelationId,
Relations.TYPE to ObjectTypeIds.RELATION,
Relations.RELATION_KEY to setByRelationKey
)
val pageTypeId = ObjectState.VIEW_DEFAULT_OBJECT_TYPE
val pageTemplate1 = StubObject(
id = "pagetemplate1-${RandomString.make()}",
objectType = ObjectTypeIds.TEMPLATE,
targetObjectType = pageTypeId
)
val pageTemplate2 = StubObject(
id = "pagetemplate2-${RandomString.make()}",
objectType = ObjectTypeIds.TEMPLATE,
targetObjectType = pageTypeId
)
val customType1Id = "customType1-${RandomString.make()}"
val template1 = StubObject(
id = "template1-${RandomString.make()}",
objectType = ObjectTypeIds.TEMPLATE,
targetObjectType = customType1Id
)
val template2 = StubObject(
id = "template2-${RandomString.make()}",
objectType = ObjectTypeIds.TEMPLATE,
targetObjectType = customType1Id
)
val setObjDetails = mapOf(
Relations.ID to root,
Relations.LAYOUT to ObjectType.Layout.SET.code.toDouble(),
Relations.SET_OF to listOf(setByRelationId),
)
@Before
fun setup() {
closable = MockitoAnnotations.openMocks(this)
viewModel = givenViewModel()
}
@After
fun after() {
rule.advanceTime()
closable.close()
}
/**
* Set by relation,
* SetOf: Relation1
* View default type : PAGE
* View default template : empty
* PAGE type default template : empty
*/
@Test
fun `set by relation, view type and template are empty, page template empty`() = runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = null,
defaultTemplateId = null
)
val dv = StubDataView(views = listOf(viewer), relationLinks = listOf(relationLink1))
val dvKeys = listOf(relationObject1.key)
val pageTypeMap = mapOf(
Relations.ID to pageTypeId,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.BASIC.code.toDouble(),
Relations.NAME to MockDataFactory.randomString(),
Relations.DEFAULT_TEMPLATE_ID to null
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = setObjDetails),
setByRelationId to Block.Fields(map = setByRelationMap),
pageTypeId to Block.Fields(map = pageTypeMap)
)
)
with(storeOfObjectTypes) {
set(pageTypeId, pageTypeMap)
}
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv), details = details
)
stubTemplatesContainer(
type = pageTypeId, templates = listOf(pageTemplate1, pageTemplate2)
)
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
sources = listOf(setByRelationId),
objects = listOf()
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT BLANK IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Blank)
val uiState = viewModel.currentViewer.value as DataViewViewState.Set.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.SetByRelation(
filters = listOf(),
type = pageTypeId,
template = null,
relations = listOf(setByRelationId),
)
async(params)
}
}
/**
* Set by relation,
* SetOf: Relation1
* View default type : PAGE
* View default template : empty
* PAGE type default template : Blank
*/
@Test
fun `set by relation, view type and template are empty, page template blank`() = runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = null,
defaultTemplateId = null
)
val dv = StubDataView(views = listOf(viewer), relationLinks = listOf(relationLink1))
val dvKeys = listOf(relationObject1.key)
val pageTypeMap = mapOf(
Relations.ID to pageTypeId,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.BASIC.code.toDouble(),
Relations.NAME to MockDataFactory.randomString(),
Relations.DEFAULT_TEMPLATE_ID to DEFAULT_TEMPLATE_ID_BLANK
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = setObjDetails),
setByRelationId to Block.Fields(map = setByRelationMap),
pageTypeId to Block.Fields(map = pageTypeMap)
)
)
with(storeOfObjectTypes) {
set(pageTypeId, pageTypeMap)
}
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv), details = details
)
stubTemplatesContainer(
type = pageTypeId, templates = listOf(pageTemplate1, pageTemplate2)
)
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
sources = listOf(setByRelationId),
objects = listOf()
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT BLANK IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Blank)
val uiState = viewModel.currentViewer.value as DataViewViewState.Set.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.SetByRelation(
filters = listOf(),
type = pageTypeId,
template = null,
relations = listOf(setByRelationId),
)
async(params)
}
}
/**
* Set by relation,
* SetOf: Relation1
* View default type : PAGE
* View default template : empty
* PAGE type default template : Custom
*/
@Test
fun `set by relation, view type and template are empty, page template custom`() = runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = null,
defaultTemplateId = null
)
val dv = StubDataView(views = listOf(viewer), relationLinks = listOf(relationLink1))
val dvKeys = listOf(relationObject1.key)
val pageTypeMap = mapOf(
Relations.ID to pageTypeId,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.BASIC.code.toDouble(),
Relations.NAME to MockDataFactory.randomString(),
Relations.DEFAULT_TEMPLATE_ID to pageTemplate2.id
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = setObjDetails),
setByRelationId to Block.Fields(map = setByRelationMap),
pageTypeId to Block.Fields(map = pageTypeMap)
)
)
with(storeOfObjectTypes) {
set(pageTypeId, pageTypeMap)
}
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv), details = details
)
stubTemplatesContainer(
type = pageTypeId, templates = listOf(pageTemplate1, pageTemplate2)
)
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
sources = listOf(setByRelationId),
objects = listOf()
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT TEMPLATE IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Template)
val uiState = viewModel.currentViewer.value as DataViewViewState.Set.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.SetByRelation(
filters = listOf(),
type = pageTypeId,
template = pageTemplate2.id,
relations = listOf(setByRelationId),
)
async(params)
}
}
/**
* Set by relation,
* SetOf: Relation1
* View default type : CUSTOM
* View default template : empty
* CUSTOM type default template : template1
*/
@Test
fun `set by relation, view type is custom and template is empty, custom type template is not empty`() =
runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = customType1Id,
defaultTemplateId = null
)
val dv = StubDataView(views = listOf(viewer), relationLinks = listOf(relationLink1))
val dvKeys = listOf(relationObject1.key)
val pageTypeMap = mapOf(
Relations.ID to pageTypeId,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.BASIC.code.toDouble(),
Relations.NAME to MockDataFactory.randomString(),
Relations.DEFAULT_TEMPLATE_ID to pageTemplate1.id
)
val customType1Map = mapOf(
Relations.ID to customType1Id,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.TODO.code.toDouble(),
Relations.NAME to "name-$customType1Id",
Relations.DEFAULT_TEMPLATE_ID to template1.id
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = setObjDetails),
setByRelationId to Block.Fields(map = setByRelationMap),
pageTypeId to Block.Fields(map = pageTypeMap),
customType1Id to Block.Fields(map = customType1Map)
)
)
with(storeOfObjectTypes) {
set(pageTypeId, pageTypeMap)
set(customType1Id, customType1Map)
}
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv), details = details
)
stubTemplatesContainer(
type = customType1Id, templates = listOf(template2, template1)
)
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
sources = listOf(setByRelationId),
objects = listOf()
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT TEMPLATE IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Template)
val uiState = viewModel.currentViewer.value as DataViewViewState.Set.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.SetByRelation(
filters = listOf(),
type = customType1Id,
template = template1.id,
relations = listOf(setByRelationId),
)
async(params)
}
}
/**
* Set by relation,
* SetOf: Relation1
* View default type : CUSTOM
* View default template : empty
* CUSTOM type default template : empty
*/
@Test
fun `set by relation, view type is custom and template is empty, custom type template is empty`() =
runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = customType1Id,
defaultTemplateId = null
)
val dv = StubDataView(views = listOf(viewer), relationLinks = listOf(relationLink1))
val dvKeys = listOf(relationObject1.key)
val pageTypeMap = mapOf(
Relations.ID to pageTypeId,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.BASIC.code.toDouble(),
Relations.NAME to MockDataFactory.randomString(),
Relations.DEFAULT_TEMPLATE_ID to pageTemplate1.id
)
val customType1Map = mapOf(
Relations.ID to customType1Id,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.TODO.code.toDouble(),
Relations.NAME to "name-$customType1Id",
Relations.DEFAULT_TEMPLATE_ID to null
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = setObjDetails),
setByRelationId to Block.Fields(map = setByRelationMap),
pageTypeId to Block.Fields(map = pageTypeMap),
customType1Id to Block.Fields(map = customType1Map)
)
)
with(storeOfObjectTypes) {
set(pageTypeId, pageTypeMap)
set(customType1Id, customType1Map)
}
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv), details = details
)
stubTemplatesContainer(
type = customType1Id, templates = listOf(template2, template1)
)
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
sources = listOf(setByRelationId),
objects = listOf()
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT BLANK IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Blank)
val uiState = viewModel.currentViewer.value as DataViewViewState.Set.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.SetByRelation(
filters = listOf(),
type = customType1Id,
template = null,
relations = listOf(setByRelationId),
)
async(params)
}
}
/**
* Set by relation,
* SetOf: Relation1
* View default type : CUSTOM
* View default template : empty
* CUSTOM type default template : blank
*/
@Test
fun `set by relation, view type is custom and template is empty, custom type template is blank`() =
runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = customType1Id,
defaultTemplateId = null
)
val dv = StubDataView(views = listOf(viewer), relationLinks = listOf(relationLink1))
val dvKeys = listOf(relationObject1.key)
val pageTypeMap = mapOf(
Relations.ID to pageTypeId,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.BASIC.code.toDouble(),
Relations.NAME to MockDataFactory.randomString(),
Relations.DEFAULT_TEMPLATE_ID to pageTemplate1.id
)
val customType1Map = mapOf(
Relations.ID to customType1Id,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.TODO.code.toDouble(),
Relations.NAME to "name-$customType1Id",
Relations.DEFAULT_TEMPLATE_ID to DEFAULT_TEMPLATE_ID_BLANK
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = setObjDetails),
setByRelationId to Block.Fields(map = setByRelationMap),
pageTypeId to Block.Fields(map = pageTypeMap),
customType1Id to Block.Fields(map = customType1Map)
)
)
with(storeOfObjectTypes) {
set(pageTypeId, pageTypeMap)
set(customType1Id, customType1Map)
}
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv), details = details
)
stubTemplatesContainer(
type = customType1Id, templates = listOf(template2, template1)
)
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
sources = listOf(setByRelationId),
objects = listOf()
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT BLANK IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Blank)
val uiState = viewModel.currentViewer.value as DataViewViewState.Set.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.SetByRelation(
filters = listOf(),
type = customType1Id,
template = null,
relations = listOf(setByRelationId),
)
async(params)
}
}
/**
* Set by relation,
* SetOf: Relation1
* View default type : CUSTOM
* View default template : Blank
* CUSTOM type default template : Template1
*/
@Test
fun `set by relation, view type is custom and template is blank, custom type template is not empty`() =
runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = customType1Id,
defaultTemplateId = DEFAULT_TEMPLATE_ID_BLANK
)
val dv = StubDataView(views = listOf(viewer), relationLinks = listOf(relationLink1))
val dvKeys = listOf(relationObject1.key)
val pageTypeMap = mapOf(
Relations.ID to pageTypeId,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.BASIC.code.toDouble(),
Relations.NAME to MockDataFactory.randomString(),
Relations.DEFAULT_TEMPLATE_ID to pageTemplate1.id
)
val customType1Map = mapOf(
Relations.ID to customType1Id,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.TODO.code.toDouble(),
Relations.NAME to "name-$customType1Id",
Relations.DEFAULT_TEMPLATE_ID to template1.id
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = setObjDetails),
setByRelationId to Block.Fields(map = setByRelationMap),
pageTypeId to Block.Fields(map = pageTypeMap),
customType1Id to Block.Fields(map = customType1Map)
)
)
with(storeOfObjectTypes) {
set(pageTypeId, pageTypeMap)
set(customType1Id, customType1Map)
}
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv), details = details
)
stubTemplatesContainer(
type = customType1Id, templates = listOf(template2, template1)
)
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
sources = listOf(setByRelationId),
objects = listOf()
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT BLANK IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Blank)
val uiState = viewModel.currentViewer.value as DataViewViewState.Set.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.SetByRelation(
filters = listOf(),
type = customType1Id,
template = null,
relations = listOf(setByRelationId),
)
async(params)
}
}
/**
* Set by relation,
* SetOf: Relation1
* View default type : CUSTOM
* View default template : Template2
* CUSTOM type default template : Template1
*/
@Test
fun `set by relation, view type is custom and template is not empty, custom type template is different`() =
runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = customType1Id,
defaultTemplateId = template2.id
)
val dv = StubDataView(views = listOf(viewer), relationLinks = listOf(relationLink1))
val dvKeys = listOf(relationObject1.key)
val pageTypeMap = mapOf(
Relations.ID to pageTypeId,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.BASIC.code.toDouble(),
Relations.NAME to MockDataFactory.randomString(),
Relations.DEFAULT_TEMPLATE_ID to pageTemplate1.id
)
val customType1Map = mapOf(
Relations.ID to customType1Id,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.TODO.code.toDouble(),
Relations.NAME to "name-$customType1Id",
Relations.DEFAULT_TEMPLATE_ID to template1.id
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = setObjDetails),
setByRelationId to Block.Fields(map = setByRelationMap),
pageTypeId to Block.Fields(map = pageTypeMap),
customType1Id to Block.Fields(map = customType1Map)
)
)
with(storeOfObjectTypes) {
set(pageTypeId, pageTypeMap)
set(customType1Id, customType1Map)
}
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv), details = details
)
stubTemplatesContainer(
type = customType1Id, templates = listOf(template2, template1)
)
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
sources = listOf(setByRelationId),
objects = listOf()
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT TEMPLATE IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Template)
val uiState = viewModel.currentViewer.value as DataViewViewState.Set.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.SetByRelation(
filters = listOf(),
type = customType1Id,
template = template2.id,
relations = listOf(setByRelationId),
)
async(params)
}
}
}

View file

@ -0,0 +1,639 @@
package com.anytypeio.anytype.presentation.templates
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.ObjectTypeIds
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.StubDataView
import com.anytypeio.anytype.core_models.StubDataViewView
import com.anytypeio.anytype.core_models.StubDataViewViewRelation
import com.anytypeio.anytype.core_models.StubObject
import com.anytypeio.anytype.core_models.StubRelationLink
import com.anytypeio.anytype.core_models.StubRelationObject
import com.anytypeio.anytype.domain.dataview.interactor.CreateDataViewObject
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.subscription.DefaultDataViewSubscription
import com.anytypeio.anytype.presentation.templates.TemplateView.Companion.DEFAULT_TEMPLATE_ID_BLANK
import kotlin.test.assertEquals
import kotlin.test.assertTrue
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.times
import org.mockito.kotlin.verifyBlocking
@OptIn(ExperimentalCoroutinesApi::class)
class SetByTypeViewerTypeAndTemplateTest : ObjectSetViewModelTestSetup() {
private lateinit var viewModel: ObjectSetViewModel
private lateinit var closable: AutoCloseable
private val customType1Id = "customType1-${RandomString.make()}"
private val template1 = StubObject(
id = "template1-${RandomString.make()}",
objectType = ObjectTypeIds.TEMPLATE,
targetObjectType = customType1Id
)
private val template2 = StubObject(
id = "template2-${RandomString.make()}",
objectType = ObjectTypeIds.TEMPLATE,
targetObjectType = customType1Id
)
private val setObjDetails = mapOf(
Relations.ID to root,
Relations.LAYOUT to ObjectType.Layout.SET.code.toDouble(),
Relations.SET_OF to listOf(customType1Id)
)
@Before
fun setup() {
closable = MockitoAnnotations.openMocks(this)
viewModel = givenViewModel()
}
@After
fun after() {
rule.advanceTime()
closable.close()
}
/**
* Set by type,
* SetOf: Type1
* Type1 default template : empty
* View default type : empty
* View default template : empty
*/
@Test
fun `set by type, type default template is empty, views settings are empty`() = runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = null,
defaultTemplateId = null
)
val dv = StubDataView(views = listOf(viewer), relationLinks = listOf(relationLink1))
val dvKeys = listOf(relationObject1.key)
val customType1Map = mapOf(
Relations.ID to customType1Id,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.TODO.code.toDouble(),
Relations.NAME to "name-$customType1Id",
Relations.DEFAULT_TEMPLATE_ID to null
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = setObjDetails),
customType1Id to Block.Fields(map = customType1Map)
)
)
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv),
details = details
)
stubTemplatesContainer(
type = customType1Id,
templates = listOf(template1, template2)
)
with(storeOfObjectTypes) {
set(customType1Id, customType1Map)
}
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
sources = listOf(customType1Id),
objects = listOf()
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT BLANK IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Blank)
val uiState = viewModel.currentViewer.value as DataViewViewState.Set.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.SetByType(
filters = listOf(),
type = customType1Id,
template = null,
)
async(params)
}
}
/**
* Set by type,
* SetOf: Type1
* Type1 default template : Blank
* View default type : empty
* View default template : empty
*/
@Test
fun `set by type, type default template is blank, views settings are empty`() = runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = null,
defaultTemplateId = null
)
val dv = StubDataView(views = listOf(viewer), relationLinks = listOf(relationLink1))
val dvKeys = listOf(relationObject1.key)
val customType1Map = mapOf(
Relations.ID to customType1Id,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.TODO.code.toDouble(),
Relations.NAME to "name-$customType1Id",
Relations.DEFAULT_TEMPLATE_ID to DEFAULT_TEMPLATE_ID_BLANK
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = setObjDetails),
customType1Id to Block.Fields(map = customType1Map)
)
)
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv),
details = details
)
stubTemplatesContainer(
type = customType1Id,
templates = listOf(template1, template2)
)
with(storeOfObjectTypes) {
set(customType1Id, customType1Map)
}
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
sources = listOf(customType1Id),
objects = listOf()
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT BLANK IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Blank)
val uiState = viewModel.currentViewer.value as DataViewViewState.Set.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.SetByType(
filters = listOf(),
type = customType1Id,
template = null,
)
async(params)
}
}
/**
* Set by type,
* SetOf: Type1
* Type1 default template : Template2
* View default type : empty
* View default template : empty
*/
@Test
fun `set by type, type default template is not blank, views settings are empty`() = runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = null,
defaultTemplateId = null
)
val dv = StubDataView(views = listOf(viewer), relationLinks = listOf(relationLink1))
val dvKeys = listOf(relationObject1.key)
val customType1Map = mapOf(
Relations.ID to customType1Id,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.TODO.code.toDouble(),
Relations.NAME to "name-$customType1Id",
Relations.DEFAULT_TEMPLATE_ID to template2.id
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = setObjDetails),
customType1Id to Block.Fields(map = customType1Map)
)
)
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv),
details = details
)
stubTemplatesContainer(
type = customType1Id,
templates = listOf(template1, template2)
)
with(storeOfObjectTypes) {
set(customType1Id, customType1Map)
}
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
sources = listOf(customType1Id),
objects = listOf()
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT CUSTOM TEMPLATE IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Template)
val uiState = viewModel.currentViewer.value as DataViewViewState.Set.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.SetByType(
filters = listOf(),
type = customType1Id,
template = template2.id,
)
async(params)
}
}
/**
* Set by type,
* SetO f: Type1
* Type1 default template : Template2
* View default type : Type2
* View default template : Template1
* In that case we should ignore VIEW default type but use VIEW default template
* But this case should not happen in real life, because it's not possible to set to VIEW a different type other then setOf
*/
@Test
fun `set by type, type default template is not blank, views settings has different type and template`() =
runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val dvKeys = listOf(relationObject1.key)
val customType1Map = mapOf(
Relations.ID to customType1Id,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.TODO.code.toDouble(),
Relations.NAME to "name-$customType1Id",
Relations.DEFAULT_TEMPLATE_ID to template2.id
)
val customType2Id = "customType2-${RandomString.make()}"
val customType2Map = mapOf(
Relations.ID to customType2Id,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.TODO.code.toDouble(),
Relations.NAME to RandomString.make(),
Relations.DEFAULT_TEMPLATE_ID to template1.id
)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = customType2Id,
defaultTemplateId = template1.id
)
val dv = StubDataView(views = listOf(viewer), relationLinks = listOf(relationLink1))
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = setObjDetails),
customType1Id to Block.Fields(map = customType1Map),
customType2Id to Block.Fields(map = customType2Map)
)
)
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv),
details = details
)
stubTemplatesContainer(
type = customType1Id,
templates = listOf(template1, template2)
)
with(storeOfObjectTypes) {
set(customType1Id, customType1Map)
}
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
sources = listOf(customType1Id),
objects = listOf()
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT CUSTOM TEMPLATE IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Template)
val uiState = viewModel.currentViewer.value as DataViewViewState.Set.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.SetByType(
filters = listOf(),
type = customType1Id,
template = template1.id,
)
async(params)
}
}
/**
* Set by type,
* SetOf: Type1
* Type1 default template : Template2
* View default type : empty
* View default template : Template1
*/
@Test
fun `set by type, type default template is not blank, view template is different`() = runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = null,
defaultTemplateId = template1.id
)
val dv = StubDataView(views = listOf(viewer), relationLinks = listOf(relationLink1))
val dvKeys = listOf(relationObject1.key)
val customType1Map = mapOf(
Relations.ID to customType1Id,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.TODO.code.toDouble(),
Relations.NAME to "name-$customType1Id",
Relations.DEFAULT_TEMPLATE_ID to template2.id
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = setObjDetails),
customType1Id to Block.Fields(map = customType1Map)
)
)
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv),
details = details
)
stubTemplatesContainer(
type = customType1Id,
templates = listOf(template1, template2)
)
with(storeOfObjectTypes) {
set(customType1Id, customType1Map)
}
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
sources = listOf(customType1Id),
objects = listOf()
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT CUSTOM TEMPLATE IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Template)
val uiState = viewModel.currentViewer.value as DataViewViewState.Set.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.SetByType(
filters = listOf(),
type = customType1Id,
template = template1.id,
)
async(params)
}
}
/**
* Set by type,
* SetOf: Type1
* Type1 default template : Template2
* View default type : empty
* View default template : Blank
*/
@Test
fun `set by type, type default template is not blank, view template is blank`() = runTest {
val workspaceId = RandomString.make()
val subscriptionId = DefaultDataViewSubscription.getSubscriptionId(root)
val relationObject1 = StubRelationObject()
val dvViewerRelation1 =
StubDataViewViewRelation(key = relationObject1.key, isVisible = true)
val relationLink1 = StubRelationLink(relationObject1.key)
val viewer = StubDataViewView(
viewerRelations = listOf(dvViewerRelation1),
defaultObjectType = null,
defaultTemplateId = DEFAULT_TEMPLATE_ID_BLANK
)
val dv = StubDataView(views = listOf(viewer), relationLinks = listOf(relationLink1))
val dvKeys = listOf(relationObject1.key)
val customType1Map = mapOf(
Relations.ID to customType1Id,
Relations.TYPE to ObjectTypeIds.OBJECT_TYPE,
Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.TODO.code.toDouble(),
Relations.NAME to "name-$customType1Id",
Relations.DEFAULT_TEMPLATE_ID to template2.id
)
val details = Block.Details(
details = mapOf(
root to Block.Fields(map = setObjDetails),
customType1Id to Block.Fields(map = customType1Map)
)
)
stubWorkspaceManager(workspaceId)
stubInterceptEvents()
stubInterceptThreadStatus()
stubOpenObject(
doc = listOf(dv),
details = details
)
stubTemplatesContainer(
type = customType1Id,
templates = listOf(template1, template2)
)
with(storeOfObjectTypes) {
set(customType1Id, customType1Map)
}
stubSubscriptionResults(
subscription = subscriptionId,
workspace = workspaceId,
storeOfRelations = storeOfRelations,
keys = dvKeys,
sources = listOf(customType1Id),
objects = listOf()
)
stubCreateDataViewObject()
//TESTING
viewModel.onStart(ctx = root)
advanceUntilIdle()
val result = viewModel.templatesWidgetState.value.items.filter { it.isDefault }
// ASSERT CUSTOM TEMPLATE IS DEFAULT
assertEquals(1, result.size)
assertTrue(result[0] is TemplateView.Blank)
val uiState = viewModel.currentViewer.value as DataViewViewState.Set.NoItems
// ASSERT NEW + BUTTON
assertTrue(uiState.hasTemplates)
viewModel.proceedWithDataViewObjectCreate()
advanceUntilIdle()
// ASSERT OBJECT CREATION ON NEW BUTTON CLICK
verifyBlocking(createDataViewObject, times(1)) {
val params = CreateDataViewObject.Params.SetByType(
filters = listOf(),
type = customType1Id,
template = null
)
async(params)
}
}
}

View file

@ -33,7 +33,8 @@ fun StubDataViewView(
hideIcon: Boolean = false,
coverFit: Boolean = false,
coverRelationKey: String? = null,
defaultObjectType: Id = ObjectTypeIds.PAGE
defaultObjectType: Id? = null,
defaultTemplateId: Id? = null
): DVViewer = DVViewer(
id = id,
filters = filters,
@ -45,7 +46,8 @@ fun StubDataViewView(
hideIcon = hideIcon,
coverFit = coverFit,
coverRelationKey = coverRelationKey,
defaultObjectType = defaultObjectType
defaultObjectType = defaultObjectType,
defaultTemplate = defaultTemplateId
)
fun StubDataViewViewRelation(

View file

@ -16,7 +16,8 @@ fun StubObject(
iconEmoji: String? = null,
isReadOnly: Boolean? = null,
isHidden: Boolean? = null,
links: List<Id> = emptyList()
links: List<Id> = emptyList(),
targetObjectType: Id? = null
): ObjectWrapper.Basic = ObjectWrapper.Basic(
map = mapOf(
Relations.ID to id,
@ -30,7 +31,8 @@ fun StubObject(
Relations.ICON_EMOJI to iconEmoji,
Relations.IS_READ_ONLY to isReadOnly,
Relations.IS_HIDDEN to isHidden,
Relations.LINKS to links
Relations.LINKS to links,
Relations.TARGET_OBJECT_TYPE to targetObjectType
)
)