diff --git a/app/src/main/java/com/anytypeio/anytype/di/feature/templates/TemplateBlankDI.kt b/app/src/main/java/com/anytypeio/anytype/di/feature/templates/TemplateBlankDI.kt index 07bf2b7c7f..ca3da7df9e 100644 --- a/app/src/main/java/com/anytypeio/anytype/di/feature/templates/TemplateBlankDI.kt +++ b/app/src/main/java/com/anytypeio/anytype/di/feature/templates/TemplateBlankDI.kt @@ -52,9 +52,15 @@ object TemplateBlankModule { @TemplateBlankScope @Provides fun provideViewModelFactory( - renderer: DefaultBlockViewRenderer + renderer: DefaultBlockViewRenderer, + storeOfRelations: StoreOfRelations, + storeOfObjectTypes: StoreOfObjectTypes, + fieldParser: FieldParser ): ViewModelProvider.Factory = TemplateBlankViewModelFactory( - renderer = renderer + renderer = renderer, + storeOfRelations = storeOfRelations, + storeOfObjectTypes = storeOfObjectTypes, + fieldParser = fieldParser ) @Module diff --git a/core-models/src/main/java/com/anytypeio/anytype/core_models/primitives/FieldValues.kt b/core-models/src/main/java/com/anytypeio/anytype/core_models/primitives/FieldValues.kt index f987ac9942..e75b26b51c 100644 --- a/core-models/src/main/java/com/anytypeio/anytype/core_models/primitives/FieldValues.kt +++ b/core-models/src/main/java/com/anytypeio/anytype/core_models/primitives/FieldValues.kt @@ -23,7 +23,7 @@ data class FieldDateValue( val relativeDate: RelativeDate ) -data class ParsedFields( +data class ParsedProperties( val header: List = emptyList(), val sidebar: List = emptyList(), val hidden: List = emptyList(), diff --git a/domain/src/main/java/com/anytypeio/anytype/domain/primitives/FieldParser.kt b/domain/src/main/java/com/anytypeio/anytype/domain/primitives/FieldParser.kt index 692b09da49..47e35e05ea 100644 --- a/domain/src/main/java/com/anytypeio/anytype/domain/primitives/FieldParser.kt +++ b/domain/src/main/java/com/anytypeio/anytype/domain/primitives/FieldParser.kt @@ -12,7 +12,7 @@ import com.anytypeio.anytype.core_models.SupportedLayouts import com.anytypeio.anytype.core_models.TimeInSeconds import com.anytypeio.anytype.core_models.primitives.Field import com.anytypeio.anytype.core_models.primitives.FieldDateValue -import com.anytypeio.anytype.core_models.primitives.ParsedFields +import com.anytypeio.anytype.core_models.primitives.ParsedProperties import com.anytypeio.anytype.core_models.primitives.SpaceId import com.anytypeio.anytype.core_models.primitives.TimestampInSeconds import com.anytypeio.anytype.core_models.primitives.Value @@ -43,21 +43,21 @@ interface FieldParser { types: List ): Pair - suspend fun getObjectParsedFields( + suspend fun getObjectParsedProperties( objectType: ObjectWrapper.Type, - objFieldKeys: List, + objPropertiesKeys: List, storeOfRelations: StoreOfRelations - ): ParsedFields + ): ParsedProperties - suspend fun getObjectTypeParsedFields( + suspend fun getObjectTypeParsedProperties( objectType: ObjectWrapper.Type, - objectTypeConflictingFieldsIds: List, + objectTypeConflictingPropertiesIds: List, storeOfRelations: StoreOfRelations - ): ParsedFields + ): ParsedProperties - fun isFieldEditable(relation: ObjectWrapper.Relation): Boolean + fun isPropertyEditable(property: ObjectWrapper.Relation): Boolean - fun isFieldCanBeDeletedFromType(field: ObjectWrapper.Relation): Boolean + fun isPropertyCanBeDeletedFromType(property: ObjectWrapper.Relation): Boolean } class FieldParserImpl @Inject constructor( @@ -200,14 +200,14 @@ class FieldParserImpl @Inject constructor( } //endregion - //region Parsed fields + //region Parsed properties - // Consolidated function to build ParsedFields. - private suspend fun getParsedFields( + // Consolidated function to build Parsed Properties. + private suspend fun getParsedProperties( objType: ObjectWrapper.Type, - localFieldIds: Collection, + localPropertiesIds: Collection, storeOfRelations: StoreOfRelations - ): ParsedFields { + ): ParsedProperties { // Clean recommended IDs based on priority. // recommendedFeaturedRelations always remain. @@ -228,46 +228,46 @@ class FieldParserImpl @Inject constructor( .filter { it !in featuredIds && it !in relationsIds && it !in fileIds } .distinct() - // Fetch valid relations for each recommended group. - val headerFields = storeOfRelations.getValidRelations(ids = featuredIds) - val sidebarFields = storeOfRelations.getValidRelations(ids = relationsIds) - val fileFields = storeOfRelations.getValidRelations(ids = fileIds) - val hiddenFields = storeOfRelations.getValidRelations(ids = hiddenIds) + // Fetch valid properties for each recommended group. + val headerProperties = storeOfRelations.getValidRelations(ids = featuredIds) + val sidebarProperties = storeOfRelations.getValidRelations(ids = relationsIds) + val fileProperties = storeOfRelations.getValidRelations(ids = fileIds) + val hiddenProperties = storeOfRelations.getValidRelations(ids = hiddenIds) - // Combine IDs from all recommended relations. - val existingIds = (headerFields + sidebarFields + hiddenFields + fileFields) + // Combine IDs from all recommended properties. + val existingIds = (headerProperties + sidebarProperties + hiddenProperties + fileProperties) .map { it.id } .toSet() - // Filter out fields already present in the recommended groups. - val allLocalFields = storeOfRelations.getValidRelations( - ids = localFieldIds + // Filter out properties already present in the recommended groups. + val allLocalProperties = storeOfRelations.getValidRelations( + ids = localPropertiesIds .filter { it !in existingIds } .toList() ) - // Partition local fields into system and non-system fields. - val (localSystemFields, localFieldsWithoutSystem) = allLocalFields.partition { + // Partition local properties into system and non-system properties. + val (localSystemProperties, localPropertiesWithoutSystem) = allLocalProperties.partition { Relations.systemRelationKeys.contains(it.key) } - return ParsedFields( - header = headerFields, - sidebar = sidebarFields, - hidden = hiddenFields, - localWithoutSystem = localFieldsWithoutSystem, - localSystem = localSystemFields, - file = fileFields + return ParsedProperties( + header = headerProperties, + sidebar = sidebarProperties, + hidden = hiddenProperties, + localWithoutSystem = localPropertiesWithoutSystem, + localSystem = localSystemProperties, + file = fileProperties ) } - override suspend fun getObjectParsedFields( + override suspend fun getObjectParsedProperties( objectType: ObjectWrapper.Type, - objFieldKeys: List, + objPropertiesKeys: List, storeOfRelations: StoreOfRelations - ): ParsedFields { + ): ParsedProperties { val localFieldIds = storeOfRelations.getByKeys( - keys = objFieldKeys + keys = objPropertiesKeys ).mapNotNull { if (it.isValidToUse) { it.id @@ -275,26 +275,26 @@ class FieldParserImpl @Inject constructor( null } } - return getParsedFields( + return getParsedProperties( objType = objectType, - localFieldIds = localFieldIds, + localPropertiesIds = localFieldIds, storeOfRelations = storeOfRelations ) } - override suspend fun getObjectTypeParsedFields( + override suspend fun getObjectTypeParsedProperties( objectType: ObjectWrapper.Type, - objectTypeConflictingFieldsIds: List, + objectTypeConflictingPropertiesIds: List, storeOfRelations: StoreOfRelations - ): ParsedFields { - return getParsedFields( + ): ParsedProperties { + return getParsedProperties( objType = objectType, - localFieldIds = objectTypeConflictingFieldsIds, + localPropertiesIds = objectTypeConflictingPropertiesIds, storeOfRelations = storeOfRelations ) } - override fun isFieldEditable(relation: ObjectWrapper.Relation): Boolean { + override fun isPropertyEditable(relation: ObjectWrapper.Relation): Boolean { return !(relation.isReadOnly == true || relation.isHidden == true || relation.isArchived == true || @@ -302,8 +302,8 @@ class FieldParserImpl @Inject constructor( Relations.systemRelationKeys.contains(relation.key)) } - override fun isFieldCanBeDeletedFromType(field: ObjectWrapper.Relation): Boolean { - return !(field.isHidden == true || Relations.systemRelationKeys.contains(field.key)) + override fun isPropertyCanBeDeletedFromType(property: ObjectWrapper.Relation): Boolean { + return !(property.isHidden == true || Relations.systemRelationKeys.contains(property.key)) } //endregion } \ No newline at end of file diff --git a/feature-object-type/src/main/java/com/anytypeio/anytype/feature_object_type/ui/UiStateExt.kt b/feature-object-type/src/main/java/com/anytypeio/anytype/feature_object_type/ui/UiStateExt.kt index fca00fad22..12bbbef899 100644 --- a/feature-object-type/src/main/java/com/anytypeio/anytype/feature_object_type/ui/UiStateExt.kt +++ b/feature-object-type/src/main/java/com/anytypeio/anytype/feature_object_type/ui/UiStateExt.kt @@ -16,9 +16,7 @@ import com.anytypeio.anytype.domain.resources.StringResourceProvider import com.anytypeio.anytype.feature_object_type.fields.UiFieldsListItem import com.anytypeio.anytype.feature_object_type.fields.UiFieldsListItem.Item import com.anytypeio.anytype.feature_object_type.fields.UiFieldsListItem.Section -import com.anytypeio.anytype.feature_properties.edit.UiPropertyLimitTypeItem import com.anytypeio.anytype.presentation.editor.cover.CoverImageHashProvider -import com.anytypeio.anytype.presentation.mapper.objectIcon import com.anytypeio.anytype.presentation.relations.BasicObjectCoverWrapper import com.anytypeio.anytype.presentation.relations.getCover import com.anytypeio.anytype.presentation.templates.TemplateView @@ -52,7 +50,7 @@ fun ObjectWrapper.Basic.toTemplateView( //endregion /** - * Extension function to safely get a name for the relation. + * Extension function to safely get a name for the property. * If the name is blank, returns a default untitled title. */ fun ObjectWrapper.Relation.getName(stringResourceProvider: StringResourceProvider): String = @@ -62,50 +60,50 @@ fun ObjectWrapper.Relation.getName(stringResourceProvider: StringResourceProvide name!! } -suspend fun buildUiFieldsList( +suspend fun buildUiPropertiesList( objType: ObjectWrapper.Type, stringResourceProvider: StringResourceProvider, fieldParser: FieldParser, storeOfObjectTypes: StoreOfObjectTypes, storeOfRelations: StoreOfRelations, - objTypeConflictingFields: List, - showHiddenFields: Boolean + objectTypeConflictingPropertiesIds: List, + showHiddenProperty: Boolean ): List { - val parsedFields = fieldParser.getObjectTypeParsedFields( + val parsedProperties = fieldParser.getObjectTypeParsedProperties( objectType = objType, storeOfRelations = storeOfRelations, - objectTypeConflictingFieldsIds = objTypeConflictingFields + objectTypeConflictingPropertiesIds = objectTypeConflictingPropertiesIds ) // The mapping functions already skip the Relations.DESCRIPTION key. - val headerItems = parsedFields.header.mapNotNull { - mapToUiFieldsDraggableListItem( - field = it, + val headerItems = parsedProperties.header.mapNotNull { + mapToUiPropertiesDraggableListItem( + property = it, stringResourceProvider = stringResourceProvider, fieldParser = fieldParser, storeOfObjectTypes = storeOfObjectTypes ) } - val sidebarItems = parsedFields.sidebar.mapNotNull { - mapToUiFieldsDraggableListItem( - field = it, + val sidebarItems = parsedProperties.sidebar.mapNotNull { + mapToUiPropertiesDraggableListItem( + property = it, stringResourceProvider = stringResourceProvider, fieldParser = fieldParser, storeOfObjectTypes = storeOfObjectTypes ) } - val hiddenItems = parsedFields.hidden.mapNotNull { - mapToUiFieldsDraggableListItem( - field = it, + val hiddenItems = parsedProperties.hidden.mapNotNull { + mapToUiPropertiesDraggableListItem( + property = it, stringResourceProvider = stringResourceProvider, fieldParser = fieldParser, storeOfObjectTypes = storeOfObjectTypes ) } - val conflictedItems = parsedFields.localWithoutSystem.mapNotNull { - mapToUiFieldsLocalListItem( - field = it, + val conflictedItems = parsedProperties.localWithoutSystem.mapNotNull { + mapToUiPropertiesLocalListItem( + property = it, stringResourceProvider = stringResourceProvider, fieldParser = fieldParser, storeOfObjectTypes = storeOfObjectTypes @@ -113,18 +111,18 @@ suspend fun buildUiFieldsList( } //this items goes to the Hidden section as draggable items - val conflictedSystemItems = parsedFields.localSystem.mapNotNull { - mapToUiFieldsDraggableListItem( - field = it, + val conflictedSystemItems = parsedProperties.localSystem.mapNotNull { + mapToUiPropertiesDraggableListItem( + property = it, stringResourceProvider = stringResourceProvider, fieldParser = fieldParser, storeOfObjectTypes = storeOfObjectTypes ) } - val fileRecommendedFields = parsedFields.file.mapNotNull { - mapToUiFieldsDraggableListItem( - field = it, + val fileRecommendedFields = parsedProperties.file.mapNotNull { + mapToUiPropertiesDraggableListItem( + property = it, stringResourceProvider = stringResourceProvider, fieldParser = fieldParser, storeOfObjectTypes = storeOfObjectTypes @@ -144,7 +142,7 @@ suspend fun buildUiFieldsList( // addAll(fileRecommendedFields) // } - if (showHiddenFields) { + if (showHiddenProperty) { add(Section.Hidden(canAdd = false)) addAll(hiddenItems) addAll(conflictedSystemItems) @@ -158,14 +156,14 @@ suspend fun buildUiFieldsList( } /** - * Shared helper to build the limit object types for a field. + * Shared helper to build the limit object types for a property. */ private suspend fun mapLimitObjectTypes( - relation: ObjectWrapper.Relation, + property: ObjectWrapper.Relation, storeOfObjectTypes: StoreOfObjectTypes ): List { - return if (relation.format == RelationFormat.OBJECT && relation.relationFormatObjectTypes.isNotEmpty()) { - relation.relationFormatObjectTypes.mapNotNull { id -> + return if (property.format == RelationFormat.OBJECT && property.relationFormatObjectTypes.isNotEmpty()) { + property.relationFormatObjectTypes.mapNotNull { id -> storeOfObjectTypes.get(id)?.let { objType -> if (objType.isValid) { objType.id @@ -180,47 +178,53 @@ private suspend fun mapLimitObjectTypes( } /** - * Maps a field to a draggable UI list item. - * Returns null if the field key equals DESCRIPTION. + * Maps a property to a draggable UI list item. + * Returns null if the property key equals DESCRIPTION. */ -private suspend fun mapToUiFieldsDraggableListItem( - field: ObjectWrapper.Relation, +private suspend fun mapToUiPropertiesDraggableListItem( + property: ObjectWrapper.Relation, stringResourceProvider: StringResourceProvider, storeOfObjectTypes: StoreOfObjectTypes, fieldParser: FieldParser ): UiFieldsListItem? { - if (field.key == Relations.DESCRIPTION) return null + if (property.key == Relations.DESCRIPTION) return null return Item.Draggable( - id = field.id, - fieldKey = field.key, - fieldTitle = field.getName(stringResourceProvider), - format = field.format, - limitObjectTypes = mapLimitObjectTypes(field, storeOfObjectTypes), - isEditableField = fieldParser.isFieldEditable(field), - isPossibleToUnlinkFromType = fieldParser.isFieldCanBeDeletedFromType(field) + id = property.id, + fieldKey = property.key, + fieldTitle = property.getName(stringResourceProvider), + format = property.format, + limitObjectTypes = mapLimitObjectTypes( + property = property, + storeOfObjectTypes = storeOfObjectTypes + ), + isEditableField = fieldParser.isPropertyEditable(property), + isPossibleToUnlinkFromType = fieldParser.isPropertyCanBeDeletedFromType(property) ) } /** - * Maps a field to a local UI list item. - * Returns null if the field key equals DESCRIPTION. + * Maps a property to a local UI list item. + * Returns null if the property key equals DESCRIPTION. */ -private suspend fun mapToUiFieldsLocalListItem( - field: ObjectWrapper.Relation, +private suspend fun mapToUiPropertiesLocalListItem( + property: ObjectWrapper.Relation, stringResourceProvider: StringResourceProvider, storeOfObjectTypes: StoreOfObjectTypes, fieldParser: FieldParser, ): UiFieldsListItem? { - if (field.key == Relations.DESCRIPTION) return null + if (property.key == Relations.DESCRIPTION) return null return Item.Local( - id = field.id, - fieldKey = field.key, - fieldTitle = field.getName(stringResourceProvider), - format = field.format, - limitObjectTypes = mapLimitObjectTypes(field, storeOfObjectTypes), - isEditableField = fieldParser.isFieldEditable(field) + id = property.id, + fieldKey = property.key, + fieldTitle = property.getName(stringResourceProvider), + format = property.format, + limitObjectTypes = mapLimitObjectTypes( + property = property, + storeOfObjectTypes = storeOfObjectTypes + ), + isEditableField = fieldParser.isPropertyEditable(property) ) } diff --git a/feature-object-type/src/main/java/com/anytypeio/anytype/feature_object_type/viewmodel/ObjectTypeViewModel.kt b/feature-object-type/src/main/java/com/anytypeio/anytype/feature_object_type/viewmodel/ObjectTypeViewModel.kt index 4ed4959d00..6d960ac1d3 100644 --- a/feature-object-type/src/main/java/com/anytypeio/anytype/feature_object_type/viewmodel/ObjectTypeViewModel.kt +++ b/feature-object-type/src/main/java/com/anytypeio/anytype/feature_object_type/viewmodel/ObjectTypeViewModel.kt @@ -49,7 +49,7 @@ import com.anytypeio.anytype.feature_object_type.ui.UiSyncStatusBadgeState import com.anytypeio.anytype.feature_object_type.ui.UiTemplatesButtonState import com.anytypeio.anytype.feature_object_type.ui.UiTemplatesModalListState import com.anytypeio.anytype.feature_object_type.ui.UiTitleState -import com.anytypeio.anytype.feature_object_type.ui.buildUiFieldsList +import com.anytypeio.anytype.feature_object_type.ui.buildUiPropertiesList import com.anytypeio.anytype.feature_object_type.ui.toTemplateView import com.anytypeio.anytype.feature_properties.edit.UiEditPropertyState import com.anytypeio.anytype.feature_properties.edit.UiEditPropertyState.Visible.View @@ -328,14 +328,14 @@ class ObjectTypeViewModel( } } updateDefaultTemplates(defaultTemplate = objType.defaultTemplateId) - val items = buildUiFieldsList( + val items = buildUiPropertiesList( objType = objType, stringResourceProvider = stringResourceProvider, fieldParser = fieldParser, storeOfObjectTypes = storeOfObjectTypes, storeOfRelations = storeOfRelations, - objTypeConflictingFields = conflictingFields, - showHiddenFields = vmParams.showHiddenFields + objectTypeConflictingPropertiesIds = conflictingFields, + showHiddenProperty = vmParams.showHiddenFields ) uiFieldsListState.value = UiFieldsListState(items = items) uiFieldsButtonState.value = UiFieldsButtonState.Visible( diff --git a/feature-object-type/src/test/java/com/anytypeio/anytype/feature_object_type/TestFieldsMappping.kt b/feature-object-type/src/test/java/com/anytypeio/anytype/feature_object_type/TestFieldsMappping.kt index ca5017ad37..baddef0b04 100644 --- a/feature-object-type/src/test/java/com/anytypeio/anytype/feature_object_type/TestFieldsMappping.kt +++ b/feature-object-type/src/test/java/com/anytypeio/anytype/feature_object_type/TestFieldsMappping.kt @@ -181,10 +181,10 @@ class TestFieldsMappping { merge(listOf(testObjectType, fieldAssigneeObjType2, fieldAssigneeObjType1)) } - val parsedFields = fieldParser.getObjectTypeParsedFields( + val parsedFields = fieldParser.getObjectTypeParsedProperties( objectType = testObjectType, storeOfRelations = storeOfRelations, - objectTypeConflictingFieldsIds = listOf() + objectTypeConflictingPropertiesIds = listOf() ) assertEquals( @@ -204,10 +204,10 @@ class TestFieldsMappping { merge(listOf(testObjectType, fieldAssigneeObjType2, fieldAssigneeObjType1)) } - val parsedFields = fieldParser.getObjectTypeParsedFields( + val parsedFields = fieldParser.getObjectTypeParsedProperties( objectType = testObjectType, storeOfRelations = storeOfRelations, - objectTypeConflictingFieldsIds = listOf() + objectTypeConflictingPropertiesIds = listOf() ) assertEquals( @@ -235,10 +235,10 @@ class TestFieldsMappping { merge(listOf(testObjectType, fieldAssigneeObjType2, fieldAssigneeObjType1)) } - val parsedFields = fieldParser.getObjectTypeParsedFields( + val parsedFields = fieldParser.getObjectTypeParsedProperties( objectType = testObjectType, storeOfRelations = storeOfRelations, - objectTypeConflictingFieldsIds = listOf() + objectTypeConflictingPropertiesIds = listOf() ) assertEquals( diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/render/DefaultBlockViewRenderer.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/render/DefaultBlockViewRenderer.kt index caaea1a96f..f5c3f29b07 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/render/DefaultBlockViewRenderer.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/editor/render/DefaultBlockViewRenderer.kt @@ -30,6 +30,7 @@ import com.anytypeio.anytype.presentation.editor.editor.model.BlockView import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Appearance.InEditor import com.anytypeio.anytype.presentation.editor.editor.model.BlockView.Mode import com.anytypeio.anytype.presentation.editor.toggle.ToggleStateHolder +import com.anytypeio.anytype.presentation.extension.getTypeForObject import com.anytypeio.anytype.presentation.mapper.objectIcon import com.anytypeio.anytype.presentation.mapper.marks import com.anytypeio.anytype.presentation.mapper.toFileView @@ -38,6 +39,7 @@ import com.anytypeio.anytype.presentation.mapper.toVideoView import com.anytypeio.anytype.presentation.mapper.toView import com.anytypeio.anytype.presentation.objects.ObjectIcon import com.anytypeio.anytype.presentation.objects.appearance.LinkAppearanceFactory +import com.anytypeio.anytype.presentation.objects.getFeaturedPropertiesIds import com.anytypeio.anytype.presentation.objects.getProperType import com.anytypeio.anytype.presentation.relations.BasicObjectCoverWrapper import com.anytypeio.anytype.presentation.relations.ObjectRelationView @@ -680,7 +682,7 @@ class DefaultBlockViewRenderer @Inject constructor( restrictions = restrictions, selection = selection, count = mCounter, - onRenderFlag = onRenderFlag, + onRenderFlag = onRenderFlag ) ) } @@ -711,12 +713,10 @@ class DefaultBlockViewRenderer @Inject constructor( val featured = featured( ctx = root.id, block = block, - details = details, - fieldParser = fieldParser, - storeOfObjectTypes = storeOfObjectTypes + details = details ) - if (featured.relations.isNotEmpty()) { + if (!featured?.relations.isNullOrEmpty()) { result.add(featured) } } @@ -2077,25 +2077,19 @@ class DefaultBlockViewRenderer @Inject constructor( private suspend fun featured( ctx: Id, block: Block, - details: ObjectViewDetails, - fieldParser: FieldParser, - storeOfObjectTypes: StoreOfObjectTypes - ): BlockView.FeaturedRelation { - val obj = details.getObject(ctx) - val featuredKeys = workaroundGlobalNameOrIdentityRelation(obj?.featuredRelations.orEmpty(), obj?.map.orEmpty()) + details: ObjectViewDetails + ): BlockView.FeaturedRelation? { + val obj = details.getObject(ctx) ?: return null val views = mapFeaturedRelations( ctx = ctx, - keys = featuredKeys, details = details, - fieldParser = fieldParser, - storeOfObjectTypes = storeOfObjectTypes - - ).sortedByDescending { it.key == Relations.TYPE || it.key == Relations.GLOBAL_NAME || it.key == Relations.IDENTITY } + currentObject = obj + ) return BlockView.FeaturedRelation( id = block.id, relations = views, - allowChangingObjectType = obj?.type?.contains(BOOKMARK) != true, - isTodoLayout = obj?.layout == ObjectType.Layout.TODO + allowChangingObjectType = obj.type.contains(BOOKMARK) != true, + isTodoLayout = obj.layout == ObjectType.Layout.TODO ) } @@ -2124,44 +2118,62 @@ class DefaultBlockViewRenderer @Inject constructor( private suspend fun mapFeaturedRelations( ctx: Id, - keys: List, + currentObject: ObjectWrapper.Basic, details: ObjectViewDetails, - fieldParser: FieldParser, - storeOfObjectTypes: StoreOfObjectTypes - ): List = keys.mapNotNull { key -> - when (key) { - Relations.DESCRIPTION -> null - Relations.TYPE -> { - val objectTypeId = details.getObject(ctx)?.getProperType() - if (objectTypeId != null) { - details.objectTypeRelation( - relationKey = key, - isFeatured = true, - objectTypeId = objectTypeId - ) - } else { - null + ): List { + + val objectFeaturedPropertiesKeys = currentObject.featuredRelations + + val featuredProperties = if (objectFeaturedPropertiesKeys.isNotEmpty()) { + objectFeaturedPropertiesKeys.mapNotNull { key -> + storeOfRelations.getByKey(key) + } + .sortedByDescending { it.key == Relations.TYPE } + } else { + currentObject.getFeaturedPropertiesIds( + storeOfRelations = storeOfRelations, + storeOfObjectTypes = storeOfObjectTypes, + fieldParser = fieldParser + ).mapNotNull { id -> + storeOfRelations.getById(id = id) + } + } + + return featuredProperties.mapNotNull { property -> + + when (property.key) { + Relations.DESCRIPTION -> null + Relations.TYPE -> { + val objectTypeId = details.getObject(ctx)?.getProperType() + if (objectTypeId != null) { + details.objectTypeRelation( + relationKey = property.key, + isFeatured = true, + objectTypeId = objectTypeId + ) + } else { + null + } + } + Relations.BACKLINKS, Relations.LINKS -> { + details.linksFeaturedRelation( + relations = storeOfRelations.getAll(), + ctx = ctx, + relationKey = property.key, + isFeatured = true + ) + } + else -> { + val values = details.getObject(ctx)?.map.orEmpty() + property.view( + details = details, + values = values, + urlBuilder = urlBuilder, + isFeatured = true, + fieldParser = fieldParser, + storeOfObjectTypes = storeOfObjectTypes + ) } - } - Relations.BACKLINKS, Relations.LINKS -> { - details.linksFeaturedRelation( - relations = storeOfRelations.getAll(), - ctx = ctx, - relationKey = key, - isFeatured = true - ) - } - else -> { - val relation = storeOfRelations.getByKey(key) - val values = details.getObject(ctx)?.map.orEmpty() - relation?.view( - details = details, - values = values, - urlBuilder = urlBuilder, - isFeatured = true, - fieldParser = fieldParser, - storeOfObjectTypes = storeOfObjectTypes - ) } } } diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/ObjectWrapperExtensions.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/ObjectWrapperExtensions.kt index d745b6ecce..8903868f44 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/ObjectWrapperExtensions.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/objects/ObjectWrapperExtensions.kt @@ -4,6 +4,7 @@ import com.anytypeio.anytype.core_models.DVViewerRelation import com.anytypeio.anytype.core_models.Id import com.anytypeio.anytype.core_models.MAX_SNIPPET_SIZE import com.anytypeio.anytype.core_models.ObjectType +import com.anytypeio.anytype.core_models.ObjectTypeIds import com.anytypeio.anytype.core_models.ObjectWrapper import com.anytypeio.anytype.core_models.RelationFormat import com.anytypeio.anytype.core_models.Relations @@ -11,6 +12,8 @@ import com.anytypeio.anytype.core_utils.ext.typeOf import com.anytypeio.anytype.domain.misc.UrlBuilder import com.anytypeio.anytype.domain.objects.ObjectStore import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes +import com.anytypeio.anytype.domain.objects.StoreOfRelations +import com.anytypeio.anytype.domain.objects.getTypeOfObject import com.anytypeio.anytype.domain.primitives.FieldParser import com.anytypeio.anytype.presentation.number.NumberParser import com.anytypeio.anytype.presentation.relations.model.DefaultObjectRelationValueView @@ -367,4 +370,41 @@ private fun updateObjectIcon(obj: ObjectView): ObjectView { is ObjectView.Default -> obj.copy(icon = ObjectIcon.None) is ObjectView.Deleted -> obj } +} + +/** + * Retrieves the list of featured header property IDs for the current [ObjectWrapper.Basic] object. + * + * All objects have an associated type which can be obtained from [StoreOfObjectTypes]. In the case that the object's + * type is a Template (i.e. its unique key equals [ObjectTypeIds.TEMPLATE]), the target object type is resolved using + * the [targetObjectType] property. Once the effective object type is determined, the function uses [FieldParser] to + * obtain parsed properties and returns the header IDs. + * + * @param storeOfObjectTypes The store that provides object types. + * @param storeOfRelations The store that provides relations between objects. + * @param fieldParser The parser used to extract parsed properties from an object. + * @return A list of header property IDs, or an empty list if the necessary object type is not found. + */ +suspend fun ObjectWrapper.Basic.getFeaturedPropertiesIds( + storeOfObjectTypes: StoreOfObjectTypes, + storeOfRelations: StoreOfRelations, + fieldParser: FieldParser, +): List { + // Retrieve the object's current type. + val currentObjType = storeOfObjectTypes.getTypeOfObject(this) ?: return emptyList() + + // Determine the effective object type. If the type is TEMPLATE, use the target object type. + val effectiveType = if (currentObjType.uniqueKey == ObjectTypeIds.TEMPLATE) { + this.targetObjectType?.let { storeOfObjectTypes.get(it) } ?: return emptyList() + } else { + currentObjType + } + + // Parse the object's properties using the effective type. + val parsedProperties = fieldParser.getObjectParsedProperties( + objectType = effectiveType, + objPropertiesKeys = this.map.keys.toList(), + storeOfRelations = storeOfRelations + ) + return parsedProperties.header.map { it.id } } \ No newline at end of file diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/relations/RelationListViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/relations/RelationListViewModel.kt index bbf2cdf777..109fb884e3 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/relations/RelationListViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/relations/RelationListViewModel.kt @@ -114,10 +114,10 @@ class RelationListViewModel( return emptyList() } - val parsedFields = fieldParser.getObjectParsedFields( + val parsedFields = fieldParser.getObjectParsedProperties( objectType = objType, storeOfRelations = storeOfRelations, - objFieldKeys = details.getObject(ctx)?.map?.keys?.toList().orEmpty() + objPropertiesKeys = details.getObject(ctx)?.map?.keys?.toList().orEmpty() ) val headerFields = parsedFields.header.mapNotNull { diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/templates/TemplateBlankViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/templates/TemplateBlankViewModel.kt index cc2635f198..38f7731bc0 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/templates/TemplateBlankViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/templates/TemplateBlankViewModel.kt @@ -11,6 +11,9 @@ import com.anytypeio.anytype.presentation.common.BaseViewModel import com.anytypeio.anytype.presentation.editor.Editor import com.anytypeio.anytype.presentation.editor.EditorViewModel import com.anytypeio.anytype.core_models.ObjectViewDetails +import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes +import com.anytypeio.anytype.domain.objects.StoreOfRelations +import com.anytypeio.anytype.domain.primitives.FieldParser import com.anytypeio.anytype.presentation.editor.editor.model.BlockView import com.anytypeio.anytype.presentation.editor.render.BlockViewRenderer import com.anytypeio.anytype.presentation.editor.render.DefaultBlockViewRenderer @@ -21,6 +24,9 @@ import timber.log.Timber class TemplateBlankViewModel( private val renderer: DefaultBlockViewRenderer, + private val storeOfRelations: StoreOfRelations, + private val storeOfObjectTypes: StoreOfObjectTypes, + private val fieldParser: FieldParser ) : BaseViewModel(), BlockViewRenderer by renderer { val state = MutableStateFlow>(emptyList()) @@ -69,14 +75,12 @@ class TemplateBlankViewModel( children = listOf(headerBlock.id), fields = Block.Fields.empty(), ) - val featuredRelations = listOf(Relations.TYPE) val page = listOf(rootBlock, headerBlock, blockTitle, featuredRelationsBlock) val objectDetails = mapOf( DEFAULT_TEMPLATE_ID_BLANK to mapOf( Relations.ID to DEFAULT_TEMPLATE_ID_BLANK, Relations.LAYOUT to layout, Relations.TYPE to typeId, - Relations.FEATURED_RELATIONS to featuredRelations, Relations.IS_DELETED to false ) ) @@ -95,6 +99,16 @@ class TemplateBlankViewModel( details = mapOf(DEFAULT_TEMPLATE_ID_BLANK to objectDetails, typeId to typeDetails)) viewModelScope.launch { + val objType = storeOfObjectTypes.get(typeId) + val featuredPropertiesIds = if (objType != null) { + fieldParser.getObjectParsedProperties( + objectType = objType, + objPropertiesKeys = listOf(), + storeOfRelations = storeOfRelations + ).header.map { it.id } + } else { + emptyList() + } state.value = page.asMap().render( context = DEFAULT_TEMPLATE_ID_BLANK, mode = Editor.Mode.Read, diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/templates/TemplateBlankViewModelFactory.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/templates/TemplateBlankViewModelFactory.kt index 0906366c8a..ed8f01f4e0 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/templates/TemplateBlankViewModelFactory.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/templates/TemplateBlankViewModelFactory.kt @@ -2,17 +2,26 @@ package com.anytypeio.anytype.presentation.templates import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes +import com.anytypeio.anytype.domain.objects.StoreOfRelations +import com.anytypeio.anytype.domain.primitives.FieldParser import com.anytypeio.anytype.presentation.editor.render.DefaultBlockViewRenderer import javax.inject.Inject class TemplateBlankViewModelFactory @Inject constructor( private val renderer: DefaultBlockViewRenderer, + private val storeOfRelations: StoreOfRelations, + private val storeOfObjectTypes: StoreOfObjectTypes, + private val fieldParser: FieldParser ) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { return TemplateBlankViewModel( - renderer = renderer + renderer = renderer, + storeOfRelations = storeOfRelations, + storeOfObjectTypes = storeOfObjectTypes, + fieldParser = fieldParser ) as T } } \ No newline at end of file diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/BlockReadModeTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/BlockReadModeTest.kt index 6fd88adddf..d6e0d2e7df 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/BlockReadModeTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/BlockReadModeTest.kt @@ -3,6 +3,8 @@ package com.anytypeio.anytype.presentation.editor import android.os.Build import com.anytypeio.anytype.core_models.Block import com.anytypeio.anytype.core_models.Event +import com.anytypeio.anytype.core_models.Relations +import com.anytypeio.anytype.core_models.Struct import com.anytypeio.anytype.core_models.ext.content import com.anytypeio.anytype.presentation.editor.editor.BlockDimensions import com.anytypeio.anytype.presentation.editor.editor.ViewState @@ -141,7 +143,13 @@ class BlockReadModeTest : EditorViewModelTest() { Event.Command.ShowObject( root = root, blocks = page, - context = root + context = root, + details = mapOf( + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ) + ) ) ) ) diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/DataViewBlockTargetObjectSetTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/DataViewBlockTargetObjectSetTest.kt index 877ecb568f..f69c15734a 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/DataViewBlockTargetObjectSetTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/DataViewBlockTargetObjectSetTest.kt @@ -127,7 +127,11 @@ class DataViewBlockTargetObjectSetTest : EditorPresentationTestSetup() { Relations.SET_OF to listOf("") ) - val detailsList = ObjectViewDetails(details = mapOf(targetObjectId to objectDetails)) + val detailsList = ObjectViewDetails(details = mapOf(targetObjectId to objectDetails, + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ))) stubOpenDocument(document = listOf(page, header, title, block, dv), details = detailsList) stubInterceptEvents(params = params) @@ -190,7 +194,15 @@ class DataViewBlockTargetObjectSetTest : EditorPresentationTestSetup() { Relations.SET_OF to emptyList() ) - val detailsList = ObjectViewDetails(details = mapOf(targetObjectId to objectDetails)) + val detailsList = ObjectViewDetails( + details = mapOf( + targetObjectId to objectDetails, + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ) + ) + ) stubOpenDocument(document = listOf(page, header, title, block, dv), details = detailsList) stubInterceptEvents(params = params) @@ -315,7 +327,15 @@ class DataViewBlockTargetObjectSetTest : EditorPresentationTestSetup() { Relations.LAYOUT to ObjectType.Layout.COLLECTION.code.toDouble() ) - val detailsList = ObjectViewDetails(details = mapOf(targetObjectId to objectDetails)) + val detailsList = ObjectViewDetails( + details = mapOf( + targetObjectId to objectDetails, + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ) + ) + ) stubOpenDocument(document = listOf(page, header, title, block, dv), details = detailsList) stubInterceptEvents(params = params) @@ -424,7 +444,6 @@ class DataViewBlockTargetObjectSetTest : EditorPresentationTestSetup() { sorts = emptyList() ) val dv = StubDataViewBlock(viewers = listOf(emptyViewer)) - val targetObjectId = MockDataFactory.randomUuid() val page = Block( id = root, fields = Block.Fields.empty(), @@ -439,7 +458,7 @@ class DataViewBlockTargetObjectSetTest : EditorPresentationTestSetup() { Event.Command.DataView.SetTargetObjectId( context = root, dv = dv.id, - targetObjectId = targetObjectId + targetObjectId = root ) ) ) @@ -449,10 +468,11 @@ class DataViewBlockTargetObjectSetTest : EditorPresentationTestSetup() { document = listOf(page, header, title, block, dv), details = ObjectViewDetails( details = mapOf( - targetObjectId to mapOf( - Relations.ID to targetObjectId, - Relations.UNIQUE_KEY to targetObjectId, - Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.BASIC.code.toDouble() + root to mapOf( + Relations.ID to root, + Relations.UNIQUE_KEY to root, + Relations.RECOMMENDED_LAYOUT to ObjectType.Layout.BASIC.code.toDouble(), + Relations.TYPE to listOf(objType.id) ) ) ) diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/DefaultBlockViewRendererTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/DefaultBlockViewRendererTest.kt index d07bd7b9ce..7575caf7c8 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/DefaultBlockViewRendererTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/DefaultBlockViewRendererTest.kt @@ -37,7 +37,6 @@ import com.anytypeio.anytype.presentation.MockBlockFactory.link import com.anytypeio.anytype.presentation.MockTypicalDocumentFactory import com.anytypeio.anytype.presentation.editor.cover.CoverImageHashProvider import com.anytypeio.anytype.core_models.ObjectViewDetails -import com.anytypeio.anytype.core_models.Struct import com.anytypeio.anytype.presentation.editor.editor.Markup import com.anytypeio.anytype.presentation.editor.editor.Markup.Companion.NON_EXISTENT_OBJECT_MENTION_NAME import com.anytypeio.anytype.presentation.editor.editor.model.Alignment @@ -51,7 +50,6 @@ import com.anytypeio.anytype.presentation.objects.ObjectIcon import com.anytypeio.anytype.presentation.util.TXT import com.anytypeio.anytype.presentation.widgets.collection.ResourceProvider import com.anytypeio.anytype.test_utils.MockDataFactory -import kotlin.random.Random import kotlin.test.assertEquals import kotlinx.coroutines.runBlocking import net.lachlanmckee.timberjunit.TimberTestRule @@ -65,31 +63,6 @@ import org.mockito.kotlin.stub class DefaultBlockViewRendererTest { - class BlockViewRenderWrapper( - private val blocks: Map>, - private val renderer: BlockViewRenderer, - private val restrictions: List = emptyList() - ) : BlockViewRenderer by renderer { - suspend fun render( - root: Block, - anchor: Id, - focus: Editor.Focus, - indent: Int, - details: ObjectViewDetails, - schema: NestedDecorationData = emptyList() - ): List = blocks.render( - context = root.id, - root = root, - focus = focus, - anchor = anchor, - indent = indent, - details = details, - restrictions = restrictions, - selection = emptySet(), - parentScheme = schema - ) - } - @get:Rule val timberTestRule: TimberTestRule = TimberTestRule.builder() .minPriority(Log.DEBUG) @@ -119,7 +92,7 @@ class DefaultBlockViewRendererTest { private lateinit var wrapper: BlockViewRenderWrapper - private var storeOfRelations: StoreOfRelations = DefaultStoreOfRelations() + val storeOfRelations = DefaultStoreOfRelations() private val storeOfObjectTypes = DefaultStoreOfObjectTypes() @@ -132,6 +105,32 @@ class DefaultBlockViewRendererTest { @Mock lateinit var stringResourceProvider: StringResourceProvider + class BlockViewRenderWrapper( + private val blocks: Map>, + private val renderer: BlockViewRenderer, + private val restrictions: List = emptyList(), + private val storeOfRelations: StoreOfRelations = DefaultStoreOfRelations() + ) : BlockViewRenderer by renderer { + suspend fun render( + root: Block, + anchor: Id, + focus: Editor.Focus, + indent: Int, + details: ObjectViewDetails, + schema: NestedDecorationData = emptyList() + ): List = blocks.render( + context = root.id, + root = root, + focus = focus, + anchor = anchor, + indent = indent, + details = details, + restrictions = restrictions, + selection = emptySet(), + parentScheme = schema, + ) + } + @Before fun setup() { MockitoAnnotations.openMocks(this) diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/EditorViewModelTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/EditorViewModelTest.kt index da9a82de65..658efbfc4d 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/EditorViewModelTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/EditorViewModelTest.kt @@ -105,6 +105,9 @@ import com.anytypeio.anytype.presentation.common.Action import com.anytypeio.anytype.presentation.common.Delegator import com.anytypeio.anytype.presentation.editor.cover.CoverImageHashProvider import com.anytypeio.anytype.core_models.ObjectViewDetails +import com.anytypeio.anytype.core_models.Relations +import com.anytypeio.anytype.core_models.StubObjectType +import com.anytypeio.anytype.core_models.primitives.ParsedProperties import com.anytypeio.anytype.presentation.editor.editor.BlockDimensions import com.anytypeio.anytype.presentation.editor.editor.Command import com.anytypeio.anytype.presentation.editor.editor.Interactor @@ -145,6 +148,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.test.runTest @@ -395,6 +399,26 @@ open class EditorViewModelTest { val delegator = Delegator.Default() + val objTypeUniqueKey = "objTypeUniqueKey-${MockDataFactory.randomString()}" + + val objType = StubObjectType( + id = MockDataFactory.randomUuid(), + uniqueKey = objTypeUniqueKey, + ) + + fun showObjectEvent(blocks: List) = Event.Command.ShowObject( + root = root, + blocks = blocks, + context = root, + details = mapOf( + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ), + objType.id to objType.map + ) + ) + val title = Block( id = MockDataFactory.randomUuid(), content = Block.Content.Text( @@ -425,6 +449,12 @@ open class EditorViewModelTest { fun setup() { MockitoAnnotations.openMocks(this) builder = UrlBuilder(gateway) + runBlocking { + storeOfObjectTypes.merge( + types = listOf(objType) + ) + } + stubParsedProperties() stubNetworkMode() stubObserveEvents() stubInterceptEvents() @@ -453,6 +483,18 @@ open class EditorViewModelTest { } } + fun stubParsedProperties() { + fieldParser.stub { + onBlocking { + getObjectParsedProperties( + objectType = any(), + objPropertiesKeys = any(), + storeOfRelations = any() + ) + } doReturn ParsedProperties() + } + } + @Test fun `should not start observing events when view model is initialized`() { givenViewModel() @@ -503,13 +545,7 @@ open class EditorViewModelTest { stubOpenPage( context = root, - events = listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) + events = listOf(showObjectEvent(page)) ) stubInterceptEvents() @@ -684,13 +720,7 @@ open class EditorViewModelTest { flow { delay(100) emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) + listOf(showObjectEvent(page)) ) delay(100) emit( @@ -779,13 +809,8 @@ open class EditorViewModelTest { stubOpenPage( context = root, - events = listOf( - Event.Command.ShowObject( - context = root, - blocks = listOf(smart, header, title, paragraph), - root = root - ) - ) + events = + listOf(showObjectEvent(listOf(smart, header, title, paragraph))) ) stubCreateBlock(root) @@ -830,11 +855,7 @@ open class EditorViewModelTest { delay(100) emit( listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) + showObjectEvent(page) ) ) delay(100) @@ -939,11 +960,7 @@ open class EditorViewModelTest { delay(100) emit( listOf( - Event.Command.ShowObject( - root = root, - blocks = blocks, - context = root - ) + showObjectEvent(blocks) ) ) } @@ -1089,15 +1106,7 @@ open class EditorViewModelTest { val events = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = blocks, - context = root - ) - ) - ) + emit(listOf(showObjectEvent(blocks))) } stubObserveEvents(events) @@ -1236,15 +1245,7 @@ open class EditorViewModelTest { val events = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = blocks, - context = root - ) - ) - ) + emit(listOf(showObjectEvent(blocks))) } stubObserveEvents(events) @@ -1313,15 +1314,7 @@ open class EditorViewModelTest { val events = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = blocks, - context = root - ) - ) - ) + emit(listOf(showObjectEvent(blocks))) } stubObserveEvents(events) @@ -1412,15 +1405,7 @@ open class EditorViewModelTest { val events = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = blocks, - context = root - ) - ) - ) + emit(listOf(showObjectEvent(blocks))) } stubObserveEvents(events) @@ -1501,15 +1486,7 @@ open class EditorViewModelTest { interceptEvents.stub { onBlocking { build() } doReturn flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = blocks, - context = root - ) - ) - ) + emit(listOf(showObjectEvent(blocks))) } } @@ -1566,15 +1543,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(1000) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent(page))) } stubObserveEvents(flow) @@ -1620,15 +1589,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(500) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = listOf(page, header, title, paragraph), - context = root - ) - ) - ) + emit(listOf(showObjectEvent(listOf(page, header, title, paragraph)))) delay(500) emit( listOf( @@ -1728,15 +1689,7 @@ open class EditorViewModelTest { val events: Flow> = flow { delay(1000) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubOpenPage() @@ -1798,15 +1751,7 @@ open class EditorViewModelTest { val doc = listOf(page, header, title, child) val events: Flow> = flow { - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = doc, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((doc)))) } stubOpenPage() @@ -1868,15 +1813,7 @@ open class EditorViewModelTest { val events: Flow> = flow { delay(pageOpenedDelay) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = doc, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((doc)))) delay(blockDeletedEventDelay) emit( listOf( @@ -1995,15 +1932,7 @@ open class EditorViewModelTest { val events: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = doc, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((doc)))) } stubOpenPage() @@ -2054,15 +1983,7 @@ open class EditorViewModelTest { val events: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubOpenPage() @@ -2110,15 +2031,7 @@ open class EditorViewModelTest { val events: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubOpenPage() @@ -2162,15 +2075,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -2233,23 +2138,14 @@ open class EditorViewModelTest { ) val flow: Flow> = flow { - delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) + stubInterceptThreadStatus() stubOpenPage(context = root) stubCreateBlock(root) stubUnlinkBlocks(root) - stubInterceptThreadStatus() givenViewModel() vm.onStart(id = root, space = defaultSpace) @@ -2303,15 +2199,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -2372,15 +2260,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -2474,15 +2354,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -2651,15 +2523,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -2716,15 +2580,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -2780,15 +2636,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -2830,15 +2678,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -2900,15 +2740,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -2973,15 +2805,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -3033,15 +2857,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -3132,15 +2948,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -3303,15 +3111,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -3588,7 +3388,14 @@ open class EditorViewModelTest { private fun givenOpenDocument( document: List = emptyList(), - details: ObjectViewDetails = ObjectViewDetails.EMPTY, + details: ObjectViewDetails = ObjectViewDetails( + details = mapOf( + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ) + ) + ), objectRestrictions: List = emptyList() ) { openPage.stub { @@ -3957,15 +3764,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -4060,15 +3859,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -4165,15 +3956,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) @@ -4306,15 +4089,7 @@ open class EditorViewModelTest { val flow: Flow> = flow { delay(100) - emit( - listOf( - Event.Command.ShowObject( - root = root, - blocks = page, - context = root - ) - ) - ) + emit(listOf(showObjectEvent((page)))) } stubObserveEvents(flow) diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorFeaturedRelationsTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorFeaturedRelationsTest.kt index 8a6274b657..47791a0ed4 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorFeaturedRelationsTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorFeaturedRelationsTest.kt @@ -5,6 +5,7 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.anytypeio.anytype.core_models.ObjectViewDetails 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.Relation import com.anytypeio.anytype.core_models.Relations import com.anytypeio.anytype.core_models.StubObject @@ -89,6 +90,12 @@ class EditorFeaturedRelationsTest : EditorPresentationTestSetup() { val r1 = MockTypicalDocumentFactory.relationObject("Ad") val r2 = MockTypicalDocumentFactory.relationObject("De") val r3 = MockTypicalDocumentFactory.relationObject("HJ") + val relationType = StubRelationObject( + id = objectTypeId, + key = Relations.TYPE, + name = "Type relation", + format = Relation.Format.LONG_TEXT + ) val value1 = MockDataFactory.randomString() val value2 = MockDataFactory.randomString() @@ -129,7 +136,7 @@ class EditorFeaturedRelationsTest : EditorPresentationTestSetup() { ) storeOfRelations.merge( - listOf(r1, r2, r3) + listOf(r1, r2, r3, relationType) ) val vm = buildViewModel() @@ -422,6 +429,12 @@ class EditorFeaturedRelationsTest : EditorPresentationTestSetup() { val r1 = MockTypicalDocumentFactory.relationObject("Ad") val r2 = MockTypicalDocumentFactory.relationObject("De") val r3 = MockTypicalDocumentFactory.relationObject("HJ") + val relationType = StubRelationObject( + id = objectTypeId, + key = Relations.TYPE, + name = "Type relation", + format = Relation.Format.LONG_TEXT + ) val value1 = MockDataFactory.randomString() val value2 = MockDataFactory.randomString() @@ -461,7 +474,7 @@ class EditorFeaturedRelationsTest : EditorPresentationTestSetup() { ) storeOfRelations.merge( - listOf(r1, r2) + listOf(r1, r2, relationType) ) val vm = buildViewModel() @@ -545,6 +558,13 @@ class EditorFeaturedRelationsTest : EditorPresentationTestSetup() { val objectTypeName = MockDataFactory.randomString() val objectTypeDescription = MockDataFactory.randomString() + val relationType = StubRelationObject( + id = objectTypeId, + key = Relations.TYPE, + name = "Type relation", + format = Relation.Format.LONG_TEXT + ) + val value1 = MockDataFactory.randomString() val value2 = MockDataFactory.randomString() val value3 = MockDataFactory.randomString() @@ -584,7 +604,7 @@ class EditorFeaturedRelationsTest : EditorPresentationTestSetup() { ) storeOfRelations.merge( - listOf(r1, r2, r3) + listOf(r1, r2, r3, relationType) ) val vm = buildViewModel() @@ -704,6 +724,13 @@ class EditorFeaturedRelationsTest : EditorPresentationTestSetup() { Relations.FEATURED_RELATIONS to listOf(Relations.TYPE, r3.key) ) + val relationType = StubRelationObject( + id = objectTypeId, + key = Relations.TYPE, + name = "Type relation", + format = Relation.Format.LONG_TEXT + ) + val customDetails = ObjectViewDetails(mapOf(root to objectFields)) stubInterceptEvents() @@ -716,7 +743,7 @@ class EditorFeaturedRelationsTest : EditorPresentationTestSetup() { ) storeOfRelations.merge( - listOf(r1, r2, r3) + listOf(r1, r2, r3, relationType) ) val vm = buildViewModel() @@ -836,8 +863,15 @@ class EditorFeaturedRelationsTest : EditorPresentationTestSetup() { ) + val relationType = StubRelationObject( + id = objectTypeId, + key = Relations.TYPE, + name = "Type relation", + format = Relation.Format.LONG_TEXT + ) + storeOfRelations.merge( - listOf(r1, r2, r3) + listOf(r1, r2, r3, relationType) ) storeOfObjectTypes.merge( @@ -1123,395 +1157,286 @@ class EditorFeaturedRelationsTest : EditorPresentationTestSetup() { } @Test - fun `should render globalName relation with proper value from global name`() = runTest { + fun `should use Featured Properties Ids from Object Type when object featured ids are empty `() = + runTest { - val title = MockTypicalDocumentFactory.title - val header = MockTypicalDocumentFactory.header - val featuredBlock = Block( - id = MockDataFactory.randomUuid(), - fields = Block.Fields.empty(), - children = emptyList(), - content = Block.Content.FeaturedRelations - ) - - val page = Block( - id = root, - fields = Block.Fields(emptyMap()), - content = Block.Content.Smart, - children = listOf(header.id, featuredBlock.id) - ) - - val doc = listOf(page, header, title, featuredBlock) - - val identityRelation = StubRelationObject( - uniqueKey = Relations.IDENTITY, - key = Relations.IDENTITY, - isHidden = true - ) - val globalNameRelation = - StubRelationObject(uniqueKey = Relations.GLOBAL_NAME, key = Relations.GLOBAL_NAME) - val identityValue = MockDataFactory.randomString() - val globalNameValue = "name123.any" - - val objectDetails = ObjectViewDetails( - mapOf( - root to - mapOf( - Relations.ID to root, - Relations.TYPE to MockDataFactory.randomString(), - Relations.FEATURED_RELATIONS to emptyList(), - Relations.IDENTITY to identityValue, - Relations.GLOBAL_NAME to globalNameValue, - Relations.LAYOUT to ObjectType.Layout.PARTICIPANT.code.toDouble() - ) + val title = MockTypicalDocumentFactory.title + val header = MockTypicalDocumentFactory.header + val block = MockTypicalDocumentFactory.a + val featuredBlock = Block( + id = MockDataFactory.randomUuid(), + fields = Block.Fields.empty(), + children = emptyList(), + content = Block.Content.FeaturedRelations ) - ) - storeOfRelations.merge( - listOf(identityRelation, globalNameRelation) - ) + val page = Block( + id = root, + fields = Block.Fields(emptyMap()), + content = Block.Content.Smart, + children = listOf(header.id, featuredBlock.id, block.id) + ) - stubGetNetworkMode() - stubInterceptEvents() - stubInterceptThreadStatus() - stubSearchObjects() - stubOpenDocument( - document = doc, - details = objectDetails, + val doc = listOf(page, header, title, block, featuredBlock) - ) + val property1 = StubRelationObject( + key = "property1-key", + name = "Property 1", + format = Relation.Format.SHORT_TEXT + ) + val property2 = StubRelationObject( + key = "property2-key", + name = "Property 2", + format = Relation.Format.SHORT_TEXT + ) - val vm = buildViewModel() + val currentObjectType = StubObjectType( + id = MockDataFactory.randomString(), + recommendedFeaturedRelations = listOf(property1.id, property2.id) + ) - vm.onStart(id = root, space = defaultSpace) + val currObject = StubObject( + id = root, + objectType = currentObjectType.id, + space = defaultSpace, + extraFields = mapOf( + property1.key to "value111", + property2.key to "value222" + ) + ) - advanceUntilIdle() + val objectDetails = ObjectViewDetails( + mapOf( + root to currObject.map, + currentObjectType.id to currentObjectType.map + ) + ) - val expected = listOf( - BlockView.Title.Profile( - id = title.id, - isFocused = false, - text = title.content().text - ), - BlockView.FeaturedRelation( - id = featuredBlock.id, - relations = listOf( - ObjectRelationView.Default( - id = globalNameRelation.id, - key = globalNameRelation.key, - name = globalNameRelation.name!!, - value = globalNameValue, - featured = true, - system = true, - readOnly = false, - format = Relation.Format.SHORT_TEXT + storeOfRelations.merge( + listOf(property1, property2) + ) + + storeOfObjectTypes.merge( + types = listOf(currentObjectType) + ) + + stubGetNetworkMode() + stubInterceptEvents() + stubInterceptThreadStatus() + stubSearchObjects() + stubOpenDocument( + document = doc, + details = objectDetails + ) + + val vm = buildViewModel() + + vm.onStart(id = root, space = defaultSpace) + + advanceUntilIdle() + + val expected = listOf( + BlockView.Title.Basic( + id = title.id, + isFocused = false, + text = title.content().text, + emoji = null + ), + BlockView.FeaturedRelation( + id = featuredBlock.id, + relations = listOf( + ObjectRelationView.Default( + id = property1.id, + key = property1.key, + name = property1.name.orEmpty(), + value = "value111", + featured = true, + format = Relation.Format.SHORT_TEXT, + system = false + ), + ObjectRelationView.Default( + id = property2.id, + key = property2.key, + name = property2.name.orEmpty(), + value = "value222", + featured = true, + format = Relation.Format.SHORT_TEXT, + system = false + ) + ) + ), + BlockView.Text.Numbered( + isFocused = false, + id = block.id, + marks = emptyList(), + background = block.parseThemeBackgroundColor(), + text = block.content().text, + alignment = block.content().align?.toView(), + number = 1, + decorations = listOf( + BlockView.Decoration( + background = block.parseThemeBackgroundColor() + ) ) ) ) - ) - assertEquals( - expected = ViewState.Success(expected), - actual = vm.state.value - ) - } + assertEquals( + expected = ViewState.Success(expected), + actual = vm.state.value + ) + } @Test - fun `should render identity relation with proper value`() = runTest { + fun `should use Featured Properties Ids from TargetObjectTypeId when object is Template and his FeatureRelations are empty`() = + runTest { - val title = MockTypicalDocumentFactory.title - val header = MockTypicalDocumentFactory.header - val featuredBlock = Block( - id = MockDataFactory.randomUuid(), - fields = Block.Fields.empty(), - children = emptyList(), - content = Block.Content.FeaturedRelations - ) - - val page = Block( - id = root, - fields = Block.Fields(emptyMap()), - content = Block.Content.Smart, - children = listOf(header.id, featuredBlock.id) - ) - - val doc = listOf(page, header, title, featuredBlock) - - val identityRelation = StubRelationObject( - uniqueKey = Relations.IDENTITY, - key = Relations.IDENTITY, - isHidden = true - ) - val globalNameRelation = - StubRelationObject(uniqueKey = Relations.GLOBAL_NAME, key = Relations.GLOBAL_NAME) - val identityValue = MockDataFactory.randomString() - val globalNameValue = "" - - val objectDetails = ObjectViewDetails( - mapOf( - root to - mapOf( - Relations.ID to root, - Relations.TYPE to MockDataFactory.randomString(), - Relations.FEATURED_RELATIONS to listOf(Relations.IDENTITY), - Relations.IDENTITY to identityValue, - Relations.GLOBAL_NAME to globalNameValue, - Relations.LAYOUT to ObjectType.Layout.PARTICIPANT.code.toDouble() - ) + val title = MockTypicalDocumentFactory.title + val header = MockTypicalDocumentFactory.header + val block = MockTypicalDocumentFactory.a + val featuredBlock = Block( + id = MockDataFactory.randomUuid(), + fields = Block.Fields.empty(), + children = emptyList(), + content = Block.Content.FeaturedRelations ) - ) - storeOfRelations.merge( - listOf(identityRelation, globalNameRelation) - ) + val page = Block( + id = root, + fields = Block.Fields(emptyMap()), + content = Block.Content.Smart, + children = listOf(header.id, featuredBlock.id, block.id) + ) - stubGetNetworkMode() - stubInterceptEvents() - stubInterceptThreadStatus() - stubSearchObjects() - stubOpenDocument( - document = doc, - details = objectDetails, + val doc = listOf(page, header, title, block, featuredBlock) - ) + val property1 = StubRelationObject( + key = "property1-key", + name = "Property 1", + format = Relation.Format.SHORT_TEXT + ) + val property2 = StubRelationObject( + key = "property2-key", + name = "Property 2", + format = Relation.Format.SHORT_TEXT + ) - val vm = buildViewModel() + val property3 = StubRelationObject( + key = "property3-key", + name = "Property 3", + format = Relation.Format.SHORT_TEXT + ) + val property4 = StubRelationObject( + key = "property4-key", + name = "Property 4", + format = Relation.Format.SHORT_TEXT + ) - vm.onStart(id = root, space = defaultSpace) + val templateObjType = StubObjectType( + id = MockDataFactory.randomString(), + uniqueKey = ObjectTypeIds.TEMPLATE, + layout = ObjectType.Layout.OBJECT_TYPE.code.toDouble(), + recommendedFeaturedRelations = listOf(property1.id, property2.id) + ) - advanceUntilIdle() + val targetObjectType = StubObjectType( + id = MockDataFactory.randomString(), + layout = ObjectType.Layout.BASIC.code.toDouble(), + recommendedFeaturedRelations = listOf(property3.id, property4.id) + ) - val expected = listOf( - BlockView.Title.Profile( - id = title.id, - isFocused = false, - text = title.content().text - ), - BlockView.FeaturedRelation( - id = featuredBlock.id, - relations = listOf( - ObjectRelationView.Default( - id = identityRelation.id, - key = identityRelation.key, - name = identityRelation.name!!, - value = identityValue, - featured = true, - system = true, - readOnly = false, - format = Relation.Format.SHORT_TEXT + val currObject = StubObject( + id = root, + objectType = templateObjType.id, + space = defaultSpace, + extraFields = mapOf( + property1.key to "value111", + property2.key to "value222", + property3.key to "value333", + property4.key to "value444", + Relations.TARGET_OBJECT_TYPE to targetObjectType.id + ) + ) + + val objectDetails = ObjectViewDetails( + mapOf( + root to currObject.map, + templateObjType.id to templateObjType.map + ) + ) + + storeOfRelations.merge( + listOf(property1, property2, property3, property4) + ) + + storeOfObjectTypes.merge( + types = listOf(templateObjType, targetObjectType) + ) + + stubGetNetworkMode() + stubInterceptEvents() + stubInterceptThreadStatus() + stubSearchObjects() + stubOpenDocument( + document = doc, + details = objectDetails + ) + + val vm = buildViewModel() + + vm.onStart(id = root, space = defaultSpace) + + advanceUntilIdle() + + val expected = listOf( + BlockView.Title.Basic( + id = title.id, + isFocused = false, + text = title.content().text, + emoji = null + ), + BlockView.FeaturedRelation( + id = featuredBlock.id, + relations = listOf( + ObjectRelationView.Default( + id = property3.id, + key = property3.key, + name = property3.name.orEmpty(), + value = "value333", + featured = true, + format = Relation.Format.SHORT_TEXT, + system = false + ), + ObjectRelationView.Default( + id = property4.id, + key = property4.key, + name = property4.name.orEmpty(), + value = "value444", + featured = true, + format = Relation.Format.SHORT_TEXT, + system = false + ) + ) + ), + BlockView.Text.Numbered( + isFocused = false, + id = block.id, + marks = emptyList(), + background = block.parseThemeBackgroundColor(), + text = block.content().text, + alignment = block.content().align?.toView(), + number = 1, + decorations = listOf( + BlockView.Decoration( + background = block.parseThemeBackgroundColor() + ) ) ) ) - ) - assertEquals( - expected = ViewState.Success(expected), - actual = vm.state.value - ) - } - - @Test - fun `should add globalName relation to featured when is present in details`() = runTest { - - val title = MockTypicalDocumentFactory.title - val header = MockTypicalDocumentFactory.header - val featuredBlock = Block( - id = MockDataFactory.randomUuid(), - fields = Block.Fields.empty(), - children = emptyList(), - content = Block.Content.FeaturedRelations - ) - - val page = Block( - id = root, - fields = Block.Fields(emptyMap()), - content = Block.Content.Smart, - children = listOf(header.id, featuredBlock.id) - ) - - val doc = listOf(page, header, title, featuredBlock) - - val globalNameRelation = - StubRelationObject(uniqueKey = Relations.GLOBAL_NAME, key = Relations.GLOBAL_NAME) - val globalNameValue = "name123.any" - val someRelationKey = MockDataFactory.randomString() - val someRelation = StubRelationObject(uniqueKey = someRelationKey, key = someRelationKey) - val someRelationValue = "Some relation Value" - - val objectDetails = ObjectViewDetails( - mapOf( - root to - mapOf( - Relations.ID to root, - Relations.TYPE to MockDataFactory.randomString(), - Relations.FEATURED_RELATIONS to listOf(someRelationKey), - Relations.GLOBAL_NAME to globalNameValue, - someRelationKey to someRelationValue, - Relations.LAYOUT to ObjectType.Layout.PARTICIPANT.code.toDouble() - ) + assertEquals( + expected = ViewState.Success(expected), + actual = vm.state.value ) - ) - - storeOfRelations.merge( - listOf(globalNameRelation, someRelation) - ) - - stubGetNetworkMode() - stubInterceptEvents() - stubInterceptThreadStatus() - stubSearchObjects() - stubOpenDocument( - document = doc, - details = objectDetails, - - ) - - val vm = buildViewModel() - - vm.onStart(id = root, space = defaultSpace) - - advanceUntilIdle() - - val expected = listOf( - BlockView.Title.Profile( - id = title.id, - isFocused = false, - text = title.content().text - ), - BlockView.FeaturedRelation( - id = featuredBlock.id, - relations = listOf( - ObjectRelationView.Default( - id = globalNameRelation.id, - key = globalNameRelation.key, - name = globalNameRelation.name!!, - value = globalNameValue, - featured = true, - system = true, - readOnly = false, - format = Relation.Format.SHORT_TEXT - ), - ObjectRelationView.Default( - id = someRelation.id, - key = someRelation.key, - name = someRelation.name!!, - value = someRelationValue, - featured = true, - system = false, - readOnly = false, - format = Relation.Format.SHORT_TEXT - ) - ) - ) - ) - - assertEquals( - expected = ViewState.Success(expected), - actual = vm.state.value - ) - } - - @Test - fun `should add identity relation to featured when identity is presented`() = runTest { - - val title = MockTypicalDocumentFactory.title - val header = MockTypicalDocumentFactory.header - val featuredBlock = Block( - id = MockDataFactory.randomUuid(), - fields = Block.Fields.empty(), - children = emptyList(), - content = Block.Content.FeaturedRelations - ) - - val page = Block( - id = root, - fields = Block.Fields(emptyMap()), - content = Block.Content.Smart, - children = listOf(header.id, featuredBlock.id) - ) - - val doc = listOf(page, header, title, featuredBlock) - - val globalNameRelation = - StubRelationObject(uniqueKey = Relations.GLOBAL_NAME, key = Relations.GLOBAL_NAME) - val globalNameValue = "name123.any" - val identityRelation = - StubRelationObject(uniqueKey = Relations.IDENTITY, key = Relations.IDENTITY) - val identityValue = MockDataFactory.randomString() - val someRelationKey = MockDataFactory.randomString() - val someRelation = StubRelationObject(uniqueKey = someRelationKey, key = someRelationKey) - val someRelationValue = "Some relation Value" - - val objectDetails = ObjectViewDetails( - mapOf( - root to - mapOf( - Relations.ID to root, - Relations.TYPE to MockDataFactory.randomString(), - Relations.FEATURED_RELATIONS to listOf(someRelationKey), - Relations.IDENTITY to identityValue, - someRelationKey to someRelationValue, - Relations.LAYOUT to ObjectType.Layout.PARTICIPANT.code.toDouble() - ) - ) - ) - - storeOfRelations.merge( - listOf(globalNameRelation, someRelation, identityRelation) - ) - - stubGetNetworkMode() - stubInterceptEvents() - stubInterceptThreadStatus() - stubSearchObjects() - stubOpenDocument( - document = doc, - details = objectDetails, - - ) - - val vm = buildViewModel() - - vm.onStart(id = root, space = defaultSpace) - - advanceUntilIdle() - - val expected = listOf( - BlockView.Title.Profile( - id = title.id, - isFocused = false, - text = title.content().text - ), - BlockView.FeaturedRelation( - id = featuredBlock.id, - relations = listOf( - ObjectRelationView.Default( - id = identityRelation.id, - key = identityRelation.key, - name = identityRelation.name!!, - value = identityValue, - featured = true, - system = true, - readOnly = false, - format = Relation.Format.SHORT_TEXT - ), - ObjectRelationView.Default( - id = someRelation.id, - key = someRelation.key, - name = someRelation.name!!, - value = someRelationValue, - featured = true, - system = false, - readOnly = false, - format = Relation.Format.SHORT_TEXT - ) - ) - ) - ) - - assertEquals( - expected = ViewState.Success(expected), - actual = vm.state.value - ) - } + } } \ No newline at end of file diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorLockPageTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorLockPageTest.kt index c84cd153d9..a65b0f9ee1 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorLockPageTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorLockPageTest.kt @@ -282,6 +282,10 @@ class EditorLockPageTest : EditorPresentationTestSetup() { document = page, details = ObjectViewDetails( mapOf( + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ), target to mapOf( Relations.ID to target, @@ -394,6 +398,10 @@ class EditorLockPageTest : EditorPresentationTestSetup() { document = page, details = ObjectViewDetails( mapOf( + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ), target to mapOf( Relations.ID to target, @@ -507,6 +515,10 @@ class EditorLockPageTest : EditorPresentationTestSetup() { document = page, details = ObjectViewDetails( mapOf( + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ), bookmarkObjectId to mapOf( Relations.ID to root, @@ -615,6 +627,10 @@ class EditorLockPageTest : EditorPresentationTestSetup() { document = page, details = ObjectViewDetails( mapOf( + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ), targetObjectId to mapOf( Relations.ID to targetObjectId, @@ -716,6 +732,10 @@ class EditorLockPageTest : EditorPresentationTestSetup() { document = page, details = ObjectViewDetails( mapOf( + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ), targetObjectId to mapOf( Relations.ID to targetObjectId, diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorMentionTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorMentionTest.kt index 246fe2c653..9575660103 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorMentionTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorMentionTest.kt @@ -171,7 +171,11 @@ class EditorMentionTest : EditorPresentationTestSetup() { Relations.ID to mentionHash, Relations.LAYOUT to Layout.BASIC.code.toDouble(), Relations.NAME to mentionText - ) + ), + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ), ) ) ) @@ -862,7 +866,11 @@ class EditorMentionTest : EditorPresentationTestSetup() { mentionTarget to mapOf( Relations.ID to mentionTarget, Relations.NAME to "" - ) + ), + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ), ), objectRestrictions = emptyList() ), @@ -1001,6 +1009,10 @@ class EditorMentionTest : EditorPresentationTestSetup() { val detailsAmend = mapOf( mentionTarget to fieldsUpdated1, + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ), ) val document = listOf(page, header, title, a) @@ -1286,6 +1298,10 @@ class EditorMentionTest : EditorPresentationTestSetup() { val detailsAmend = mapOf( mentionTarget to fieldsUpdated1, + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ), ) val document = listOf(page, header, title, a) @@ -1443,6 +1459,10 @@ class EditorMentionTest : EditorPresentationTestSetup() { val detailsAmend = mapOf( mentionTarget to fieldsUpdated1, + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ), ) val document = listOf(page, header, title, a) diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorNoteLayoutTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorNoteLayoutTest.kt index 5f0229a8ce..cb2c117f53 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorNoteLayoutTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorNoteLayoutTest.kt @@ -6,8 +6,8 @@ import app.cash.turbine.test import com.anytypeio.anytype.core_models.ObjectViewDetails import com.anytypeio.anytype.core_models.Block import com.anytypeio.anytype.core_models.ObjectType +import com.anytypeio.anytype.core_models.Relation import com.anytypeio.anytype.core_models.Relations -import com.anytypeio.anytype.core_models.StubObjectType import com.anytypeio.anytype.core_models.StubRelationObject import com.anytypeio.anytype.presentation.editor.EditorViewModel import com.anytypeio.anytype.presentation.editor.editor.model.BlockView @@ -86,20 +86,9 @@ class EditorNoteLayoutTest : EditorPresentationTestSetup() { val doc = listOf(page, header, featuredBlock) - val objectTypeId = "objectTypeId" - val objectTypeName = "objectTypeName" - val objectTypeDescription = "objectTypeDesc" - - val r1 = StubRelationObject(name = "Ad") + val r1 = StubRelationObject(name = "Ad", format = Relation.Format.SHORT_TEXT) val r2 = StubRelationObject(name = "De") val r3 = StubRelationObject(name = "HJ") - val objectRelations = listOf(r1, r2, r3) - - val objectType = StubObjectType( - id = objectTypeId, - name = "Object Type" - ) - val value1 = MockDataFactory.randomString() val value2 = MockDataFactory.randomString() @@ -110,25 +99,20 @@ class EditorNoteLayoutTest : EditorPresentationTestSetup() { r1.key to value1, r2.key to value2, r3.key to value3, - Relations.TYPE to objectType.id, - Relations.FEATURED_RELATIONS to listOf(Relations.TYPE), - Relations.LAYOUT to ObjectType.Layout.NOTE.code.toDouble() + Relations.TYPE to listOf(objType.id), + Relations.LAYOUT to ObjectType.Layout.NOTE.code.toDouble(), + Relations.FEATURED_RELATIONS to listOf(r1.key) ) - val objectTypeFields = - mapOf( - Relations.ID to objectTypeId, - Relations.UNIQUE_KEY to objectType.uniqueKey, - Relations.NAME to objectTypeName, - Relations.DESCRIPTION to objectTypeDescription - ) val customDetails = ObjectViewDetails( mapOf( root to objectFields, - objectTypeId to objectTypeFields + objType.id to objType.map ) ) + storeOfRelations.merge(listOf(r1, r2, r3)) + stubInterceptEvents() stubInterceptThreadStatus() stubSearchObjects() @@ -148,14 +132,14 @@ class EditorNoteLayoutTest : EditorPresentationTestSetup() { BlockView.FeaturedRelation( id = featuredBlock.id, relations = listOf( - ObjectRelationView.ObjectType.Base( - id = objectType.id, - key = Relations.TYPE, - name = objectTypeName, - value = null, + ObjectRelationView.Default( + id = r1.id, + key = r1.key, + name = r1.name.orEmpty(), + value = value1, featured = true, - type = objectTypeId, - system = true + system = false, + format = Relation.Format.SHORT_TEXT ) ) ) @@ -202,22 +186,12 @@ class EditorNoteLayoutTest : EditorPresentationTestSetup() { val doc = listOf(page, header, featuredBlock) - val objectTypeId = "objectTypeId" - val objectTypeName = "objectTypeName" - val objectTypeDescription = "objectTypeDesc" - - val r1 = StubRelationObject(name = "Ad") + val r1 = StubRelationObject(name = "Ad", format = Relation.Format.NUMBER) val r2 = StubRelationObject(name = "De") val r3 = StubRelationObject(name = "HJ") val objectRelations = listOf(r1, r2, r3) - val relationObjectType = StubObjectType( - id = objectTypeId, - name = "Object Type" - ) - - - val value1 = MockDataFactory.randomString() + val value1 = 123.0 val value2 = MockDataFactory.randomString() val value3 = MockDataFactory.randomString() val objectFields = @@ -226,22 +200,15 @@ class EditorNoteLayoutTest : EditorPresentationTestSetup() { r1.key to value1, r2.key to value2, r3.key to value3, - Relations.TYPE to objectTypeId, - Relations.FEATURED_RELATIONS to listOf(Relations.TYPE), + Relations.TYPE to objType.id, + Relations.FEATURED_RELATIONS to listOf(r1.key), Relations.LAYOUT to ObjectType.Layout.BASIC.code.toDouble() ) - val objectTypeFields = - mapOf( - Relations.ID to objectTypeId, - Relations.UNIQUE_KEY to MockDataFactory.randomString(), - Relations.NAME to objectTypeName, - Relations.DESCRIPTION to objectTypeDescription - ) val customDetails = ObjectViewDetails( mapOf( root to objectFields, - objectTypeId to objectTypeFields + objType.id to objType.map ) ) @@ -265,20 +232,24 @@ class EditorNoteLayoutTest : EditorPresentationTestSetup() { BlockView.FeaturedRelation( id = featuredBlock.id, relations = listOf( - ObjectRelationView.ObjectType.Base( - id = objectTypeId, - key = Relations.TYPE, - name = objectTypeName, - value = null, + ObjectRelationView.Default( + id = r1.id, + key = r1.key, + name = r1.name.orEmpty(), + value = "123", featured = true, - type = objectTypeId, - system = true + system = false, + format = Relation.Format.NUMBER ) ) ) ) - vm.state.test().assertValue(ViewState.Success(expected)) + assertEquals( + expected = ViewState.Success(expected), + actual = vm.state.value + ) + //vm.state.test().assertValue(ViewState.Success(expected)) vm.footers.test { val result = awaitItem() diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorPresentationTestSetup.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorPresentationTestSetup.kt index 0a7b17f2a1..d0b8fdc3f4 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorPresentationTestSetup.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorPresentationTestSetup.kt @@ -8,8 +8,11 @@ import com.anytypeio.anytype.core_models.Id import com.anytypeio.anytype.core_models.NetworkModeConfig import com.anytypeio.anytype.core_models.ObjectWrapper import com.anytypeio.anytype.core_models.Payload +import com.anytypeio.anytype.core_models.Relations import com.anytypeio.anytype.core_models.Response +import com.anytypeio.anytype.core_models.StubObjectType import com.anytypeio.anytype.core_models.multiplayer.SpaceMemberPermissions +import com.anytypeio.anytype.core_models.primitives.ParsedProperties import com.anytypeio.anytype.core_models.primitives.SpaceId import com.anytypeio.anytype.core_models.primitives.TypeId import com.anytypeio.anytype.core_models.primitives.TypeKey @@ -127,6 +130,7 @@ import com.anytypeio.anytype.test_utils.MockDataFactory import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.runBlocking import org.mockito.Mock import org.mockito.Mockito import org.mockito.kotlin.any @@ -395,8 +399,21 @@ open class EditorPresentationTestSetup { var permissions: UserPermissionProvider = UserPermissionProviderStub() + val objTypeUniqueKey = "objTypeUniqueKey-${MockDataFactory.randomString()}" + + val objType = StubObjectType( + id = MockDataFactory.randomUuid(), + uniqueKey = objTypeUniqueKey, + ) + open fun buildViewModel(urlBuilder: UrlBuilder = builder): EditorViewModel { + runBlocking { + storeOfObjectTypes.merge( + types = listOf(objType) + ) + } + val storage = Editor.Storage() val proxies = Editor.Proxer() val memory = Editor.Memory( @@ -527,6 +544,18 @@ open class EditorPresentationTestSetup { ) } + fun stubParsedProperties() { + fieldParser.stub { + onBlocking { + getObjectParsedProperties( + objectType = any(), + objPropertiesKeys = any(), + storeOfRelations = any() + ) + } doReturn ParsedProperties() + } + } + fun stubGetNetworkMode() { getNetworkMode.stub { onBlocking { run(Unit) } doReturn NetworkModeConfig() @@ -535,7 +564,14 @@ open class EditorPresentationTestSetup { fun stubOpenDocument( document: List = emptyList(), - details: ObjectViewDetails = ObjectViewDetails.EMPTY, + details: ObjectViewDetails = ObjectViewDetails( + details = mapOf( + root to mapOf( + Relations.ID to root, + Relations.TYPE to listOf(objType.id) + ) + ) + ), objectRestrictions: List = emptyList(), spaceId: SpaceId = SpaceId(defaultSpace) ) { diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorRelationBlockTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorRelationBlockTest.kt index 37db21d423..21c0b8cf2e 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorRelationBlockTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorRelationBlockTest.kt @@ -161,11 +161,16 @@ class EditorRelationBlockTest : EditorPresentationTestSetup() { val title = MockTypicalDocumentFactory.title val header = MockTypicalDocumentFactory.header val block = MockTypicalDocumentFactory.a + + val missedProperty = StubRelationObject( + format = Relation.Format.LONG_TEXT + ) + val relationBlock = Block( id = MockDataFactory.randomUuid(), fields = Block.Fields.empty(), children = emptyList(), - content = Block.Content.RelationBlock(key = MockDataFactory.randomString()) + content = Block.Content.RelationBlock(key = missedProperty.key) ) val page = Block( @@ -177,18 +182,9 @@ class EditorRelationBlockTest : EditorPresentationTestSetup() { val doc = listOf(page, header, title, block, relationBlock) - val objectTypeId = MockDataFactory.randomString() - val objectTypeName = MockDataFactory.randomString() - val objectTypeDescription = MockDataFactory.randomString() - val r1 = MockTypicalDocumentFactory.relationObject("Ad") val r2 = MockTypicalDocumentFactory.relationObject("De") val r3 = MockTypicalDocumentFactory.relationObject("HJ") - val relationObjectType = StubRelationObject( - key = Block.Fields.TYPE_KEY, - name = "Object Type", - format = Relation.Format.OBJECT - ) val value1 = MockDataFactory.randomString() val value2 = MockDataFactory.randomString() @@ -198,19 +194,14 @@ class EditorRelationBlockTest : EditorPresentationTestSetup() { r1.key to value1, r2.key to value2, r3.key to value3, - relationObjectType.key to objectTypeId - ) - - val objectTypeFields = - mapOf( - Relations.NAME to objectTypeName, - Relations.DESCRIPTION to objectTypeDescription + missedProperty.key to "Some Text", + Relations.ID to root, + Relations.TYPE to listOf(objType.id) ) val customDetails = ObjectViewDetails( mapOf( root to objectFields, - objectTypeId to objectTypeFields ) ) @@ -223,7 +214,7 @@ class EditorRelationBlockTest : EditorPresentationTestSetup() { ) storeOfRelations.merge( - listOf(r1, r2, r3, relationObjectType) + listOf(r1, r2, r3) ) val vm = buildViewModel() diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorSlashWidgetRelationsTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorSlashWidgetRelationsTest.kt index 86a51ff995..0d037b0c9b 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorSlashWidgetRelationsTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/EditorSlashWidgetRelationsTest.kt @@ -6,6 +6,7 @@ import com.anytypeio.anytype.core_models.ObjectViewDetails import com.anytypeio.anytype.core_models.Block import com.anytypeio.anytype.core_models.Position 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.core_models.ext.content import com.anytypeio.anytype.domain.block.interactor.CreateBlock @@ -188,7 +189,13 @@ class EditorSlashWidgetRelationsTest: EditorPresentationTestSetup() { val value1 = MockDataFactory.randomString() val value2 = MockDataFactory.randomString() val value3 = MockDataFactory.randomString() - val fields = mapOf(r1.key to value1, r2.key to value2, r3.key to value3) + val fields = mapOf( + r1.key to value1, + r2.key to value2, + r3.key to value3, + Relations.ID to root, + Relations.TYPE to listOf(objType.id), + ) val customDetails = ObjectViewDetails(mapOf(root to fields)) stubInterceptEvents() @@ -311,7 +318,8 @@ class EditorSlashWidgetRelationsTest: EditorPresentationTestSetup() { val value1 = MockDataFactory.randomString() val value2 = MockDataFactory.randomString() val value3 = MockDataFactory.randomString() - val fields = mapOf(r1.key to value1, r2.key to value2, r3.key to value3) + val fields = mapOf(r1.key to value1, r2.key to value2, r3.key to value3, Relations.ID to root, + Relations.TYPE to listOf(objType.id),) val customDetails = ObjectViewDetails(details = mapOf(root to fields)) stubInterceptEvents() @@ -503,7 +511,8 @@ class EditorSlashWidgetRelationsTest: EditorPresentationTestSetup() { val value1 = MockDataFactory.randomString() val value2 = MockDataFactory.randomString() val value3 = MockDataFactory.randomString() - val fields = mapOf(r1.key to value1, r2.key to value2, r3.key to value3) + val fields = mapOf(r1.key to value1, r2.key to value2, r3.key to value3, Relations.ID to root, + Relations.TYPE to listOf(objType.id),) val customDetails = ObjectViewDetails(mapOf(root to fields)) stubInterceptEvents() diff --git a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/table/TableBlockRendererTest.kt b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/table/TableBlockRendererTest.kt index 48dd1647a9..be9af01b88 100644 --- a/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/table/TableBlockRendererTest.kt +++ b/presentation/src/test/java/com/anytypeio/anytype/presentation/editor/editor/table/TableBlockRendererTest.kt @@ -25,6 +25,7 @@ import com.anytypeio.anytype.domain.objects.DefaultStoreOfRelations import com.anytypeio.anytype.domain.primitives.FieldParser import com.anytypeio.anytype.presentation.editor.cover.CoverImageHashProvider import com.anytypeio.anytype.core_models.ObjectViewDetails +import com.anytypeio.anytype.domain.objects.StoreOfRelations import com.anytypeio.anytype.presentation.editor.editor.model.BlockView import com.anytypeio.anytype.presentation.editor.render.BlockViewRenderer import com.anytypeio.anytype.presentation.editor.render.DefaultBlockViewRenderer