* DROID-439 App | Relations refactoring, use SearchObjects for object types (#2592) * DROID-446 Objects | Enhancement | Store relation links and process its updates (#2597) * DROID-456 Tech | Remove deprecated API for creating object types (#2601) * DROID-455 Object types | Enhancement Get object type list from ObjectSearch on Global search screen (#2602) * DROID-459 Sets | Refactoring | Use relations links instead of relations for building search params to get data view data (#2603) * DROID-458 Objects | Refactoring | Integrate new api for creating objets (#2604) * DROID-464 Relations | Refactoring | New API for creating a relation from scratch - for data view or for an object (#2605) * DROID-467 Relations | Refactoring | New API for creating options - for tags and statuses (#2607) * DROID-470 Relations | Refactoring | New API for removing any relation from an object or from a data view (#2608) * DROID-460 Tech | Object relations list (#2610) * DROID-486 Sets | Refactoring | Displaying and controlling visibility of data view relations (#2611) * DROID-500 Relations | Refactoring | Extend API of ObjectStore to be able to get a relation by its id (#2619) * DROID-459 Sets | Fix | Get relations from store by id and not by key (#2618) * DROID-489 Tech | Relations as object, add relationKey to relation connected screens (#2622) * DROID-490 Sets | Refactoring | Displaying relation values for current object in bottom sheet cells (#2629) * DROID-505 Relations | Refactoring | New interface for relations store (#2633) * DROID-509 Relations | Refactoring | Bind new relations store with subscription container (#2635) * DROID-507 Tech | MW , migration + relation links (#2636) * DROID-507 Tech | MW , migration + relation links, fixes (#2637) * DROID-517 Sets | Fix | Provide correct keys for data view search-and-subscribe query (#2641) * DROID-409 Relations | Refactoring | Use relation key instead of id when creating new relation (#2642) * DROID-521 Sets & Objects | Refactoring | Add relation to a data view or to an object from existing relations (#2644) * DROID-522 Relations | Refactoring | Add objects to relations with object format (#2645) * DROID-523 Object types | Refactoring | Implement global store for object types (#2646) * DROID-527 Object types | Refactoring | Integrate global store for object types (#2647) * DROID-531 Relations | Refactoring | Parse tag and status relations values (#2649) * DROID-535 Tech | Integrate new MW lib with migration fixes (#2653) * DROID-535 Tech | MW integration fixes (#2660) * DROID-559 Relations | Refactoring | Parse tag and status values in editor (#2662) * DROID-560 Relations | Refactoring | Integrate new lib with fixes (#2663) * DROID-561 Relations | Refactoring | Parsing tag and status values in dv (#2665) * DROID-562 Dashboard | Refactoring | Use store of object types as object type provider for favorites tab on dashboard (#2667) * DROID-567 Relations | Refactoring | Suggest available options to populate a relation (#2671) * DROID-604 Relations | Refactoring | Use details from Object.CreateRelation.Response to populate relation store (#2705) * DROID-603 Relations | Refactoring | Creating relation options + Deleting relation from object (#2706) * DROID-619 Relations | Refactoring | Migrate data view sorts and filters to the new relation-as-object paradigm (#2711) * DROID-622 Relations | Tech | Update MW to 0.24.0-rc1 (#2714) * DROID-598 Sets | Refactoring | Provide relation format for date filters (#2715) * DROID-625 Protocol | Enhancement | Integrate v0.24.0-rc2 (#2718)
563 lines
18 KiB
Kotlin
563 lines
18 KiB
Kotlin
package com.anytypeio.anytype.features.relations
|
|
|
|
import android.os.Bundle
|
|
import android.text.InputType
|
|
import androidx.core.os.bundleOf
|
|
import androidx.fragment.app.testing.FragmentScenario
|
|
import androidx.fragment.app.testing.launchFragmentInContainer
|
|
import androidx.test.espresso.Espresso.onView
|
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
|
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
|
import androidx.test.espresso.matcher.ViewMatchers.withId
|
|
import androidx.test.espresso.matcher.ViewMatchers.withInputType
|
|
import androidx.test.espresso.matcher.ViewMatchers.withText
|
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
import androidx.test.filters.LargeTest
|
|
import com.anytypeio.anytype.R
|
|
import com.anytypeio.anytype.analytics.base.Analytics
|
|
import com.anytypeio.anytype.core_models.Block
|
|
import com.anytypeio.anytype.core_models.Relation
|
|
import com.anytypeio.anytype.domain.`object`.ReloadObject
|
|
import com.anytypeio.anytype.domain.objects.DefaultObjectStore
|
|
import com.anytypeio.anytype.domain.objects.DefaultStoreOfRelations
|
|
import com.anytypeio.anytype.domain.objects.ObjectStore
|
|
import com.anytypeio.anytype.domain.objects.StoreOfRelations
|
|
import com.anytypeio.anytype.presentation.relations.ObjectSetConfig
|
|
import com.anytypeio.anytype.presentation.relations.providers.DataViewObjectRelationProvider
|
|
import com.anytypeio.anytype.presentation.relations.providers.DataViewObjectValueProvider
|
|
import com.anytypeio.anytype.presentation.sets.ObjectSet
|
|
import com.anytypeio.anytype.presentation.sets.ObjectSetDatabase
|
|
import com.anytypeio.anytype.presentation.sets.RelationTextValueViewModel
|
|
import com.anytypeio.anytype.test_utils.MockDataFactory
|
|
import com.anytypeio.anytype.test_utils.utils.espresso.TextLineCountMatcher
|
|
import com.anytypeio.anytype.ui.relations.RelationTextValueFragment
|
|
import com.anytypeio.anytype.utils.CoroutinesTestRule
|
|
import com.bartoszlipinski.disableanimationsrule.DisableAnimationsRule
|
|
import kotlinx.coroutines.flow.MutableStateFlow
|
|
import org.hamcrest.CoreMatchers.not
|
|
import org.junit.Before
|
|
import org.junit.Rule
|
|
import org.junit.Test
|
|
import org.junit.runner.RunWith
|
|
import org.mockito.Mock
|
|
import org.mockito.MockitoAnnotations
|
|
|
|
@RunWith(AndroidJUnit4::class)
|
|
@LargeTest
|
|
class DisplayObjectRelationTextValueTest {
|
|
|
|
@get:Rule
|
|
val animationsRule = DisableAnimationsRule()
|
|
|
|
@get:Rule
|
|
val coroutineTestRule = CoroutinesTestRule()
|
|
|
|
@Mock
|
|
lateinit var reloadObject: ReloadObject
|
|
|
|
@Mock
|
|
lateinit var analytics: Analytics
|
|
|
|
val root = MockDataFactory.randomUuid()
|
|
|
|
private val state = MutableStateFlow(ObjectSet.init())
|
|
private val store: ObjectStore = DefaultObjectStore()
|
|
private val storeOfRelations: StoreOfRelations = DefaultStoreOfRelations()
|
|
private val db = ObjectSetDatabase(store = store)
|
|
|
|
@Before
|
|
fun before() {
|
|
MockitoAnnotations.openMocks(this)
|
|
TestRelationTextValueFragment.testVmFactory = RelationTextValueViewModel.Factory(
|
|
relations = DataViewObjectRelationProvider(
|
|
objectSetState = state,
|
|
storeOfRelations = storeOfRelations
|
|
),
|
|
values = DataViewObjectValueProvider(db = db),
|
|
reloadObject = reloadObject,
|
|
analytics = analytics
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun shouldSetDescriptionTextAndNotDisplayActionButton() {
|
|
|
|
// SETUP
|
|
|
|
val relationText = "Architect"
|
|
val valueText = "Filippo Brunelleschi"
|
|
|
|
val target = MockDataFactory.randomUuid()
|
|
|
|
val viewer = Block.Content.DataView.Viewer(
|
|
id = MockDataFactory.randomUuid(),
|
|
name = MockDataFactory.randomString(),
|
|
filters = emptyList(),
|
|
sorts = emptyList(),
|
|
viewerRelations = emptyList(),
|
|
type = Block.Content.DataView.Viewer.Type.GRID
|
|
)
|
|
|
|
val relation = Relation(
|
|
key = MockDataFactory.randomUuid(),
|
|
name = relationText,
|
|
format = Relation.Format.SHORT_TEXT,
|
|
source = Relation.Source.values().random()
|
|
)
|
|
|
|
val record: Map<String, Any?> = mapOf(
|
|
ObjectSetConfig.ID_KEY to target,
|
|
relation.key to valueText
|
|
)
|
|
|
|
state.value = ObjectSet(
|
|
blocks = listOf(
|
|
Block(
|
|
id = MockDataFactory.randomUuid(),
|
|
children = emptyList(),
|
|
fields = Block.Fields.empty(),
|
|
content = Block.Content.DataView(
|
|
relations = listOf(relation),
|
|
viewers = listOf(viewer),
|
|
sources = listOf(
|
|
MockDataFactory.randomUuid()
|
|
)
|
|
)
|
|
)
|
|
),
|
|
// viewerDb = mapOf(
|
|
// viewer.id to ObjectSet.ViewerData(
|
|
// records = listOf(record),
|
|
// total = 1
|
|
// )
|
|
// )
|
|
)
|
|
|
|
launchFragment(
|
|
bundleOf(
|
|
RelationTextValueFragment.CONTEXT_ID to root,
|
|
RelationTextValueFragment.RELATION_ID to relation.key,
|
|
RelationTextValueFragment.OBJECT_ID to target,
|
|
RelationTextValueFragment.FLOW_KEY to RelationTextValueFragment.FLOW_DATAVIEW
|
|
)
|
|
)
|
|
|
|
// TESTING
|
|
|
|
onView(withId(R.id.textInputField)).apply {
|
|
check(matches(withText(valueText)))
|
|
}
|
|
|
|
onView(withId(R.id.tvRelationHeader)).apply {
|
|
check(matches(withText(relationText)))
|
|
}
|
|
|
|
onView(withId(R.id.btnAction)).apply {
|
|
check(matches(not(isDisplayed())))
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun shouldSetNumberTextAndNotDisplayActionButton() {
|
|
|
|
// SETUP
|
|
|
|
val relationText = "Year"
|
|
val valueText = "1446"
|
|
|
|
val target = MockDataFactory.randomUuid()
|
|
|
|
val viewer = Block.Content.DataView.Viewer(
|
|
id = MockDataFactory.randomUuid(),
|
|
name = MockDataFactory.randomString(),
|
|
filters = emptyList(),
|
|
sorts = emptyList(),
|
|
viewerRelations = emptyList(),
|
|
type = Block.Content.DataView.Viewer.Type.GRID
|
|
)
|
|
|
|
val relation = Relation(
|
|
key = MockDataFactory.randomUuid(),
|
|
name = relationText,
|
|
format = Relation.Format.NUMBER,
|
|
source = Relation.Source.values().random()
|
|
)
|
|
|
|
val record: Map<String, Any?> = mapOf(
|
|
ObjectSetConfig.ID_KEY to target,
|
|
relation.key to valueText
|
|
)
|
|
|
|
state.value = ObjectSet(
|
|
blocks = listOf(
|
|
Block(
|
|
id = MockDataFactory.randomUuid(),
|
|
children = emptyList(),
|
|
fields = Block.Fields.empty(),
|
|
content = Block.Content.DataView(
|
|
relations = listOf(relation),
|
|
viewers = listOf(viewer),
|
|
sources = listOf(
|
|
MockDataFactory.randomUuid()
|
|
)
|
|
)
|
|
)
|
|
),
|
|
// viewerDb = mapOf(
|
|
// viewer.id to ObjectSet.ViewerData(
|
|
// records = listOf(record),
|
|
// total = 1
|
|
// )
|
|
// )
|
|
)
|
|
|
|
// TESTING
|
|
|
|
launchFragment(
|
|
bundleOf(
|
|
RelationTextValueFragment.CONTEXT_ID to root,
|
|
RelationTextValueFragment.RELATION_ID to relation.key,
|
|
RelationTextValueFragment.OBJECT_ID to target,
|
|
RelationTextValueFragment.FLOW_KEY to RelationTextValueFragment.FLOW_DATAVIEW
|
|
)
|
|
)
|
|
|
|
// TESTING
|
|
|
|
onView(withId(R.id.textInputField)).apply {
|
|
check(matches(withText(valueText)))
|
|
}
|
|
|
|
onView(withId(R.id.tvRelationHeader)).apply {
|
|
check(matches(withText(relationText)))
|
|
}
|
|
|
|
onView(withId(R.id.btnAction)).apply {
|
|
check(matches(not(isDisplayed())))
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun shouldSetPhoneTextAndDisplayActionButton() {
|
|
|
|
// SETUP
|
|
|
|
val relationText = "Phone number"
|
|
val valueText = "+ 124242423423"
|
|
|
|
val target = MockDataFactory.randomUuid()
|
|
|
|
val viewer = Block.Content.DataView.Viewer(
|
|
id = MockDataFactory.randomUuid(),
|
|
name = MockDataFactory.randomString(),
|
|
filters = emptyList(),
|
|
sorts = emptyList(),
|
|
viewerRelations = emptyList(),
|
|
type = Block.Content.DataView.Viewer.Type.GRID
|
|
)
|
|
|
|
val relation = Relation(
|
|
key = MockDataFactory.randomUuid(),
|
|
name = relationText,
|
|
format = Relation.Format.PHONE,
|
|
source = Relation.Source.values().random()
|
|
)
|
|
|
|
val record: Map<String, Any?> = mapOf(
|
|
ObjectSetConfig.ID_KEY to target,
|
|
relation.key to valueText
|
|
)
|
|
|
|
state.value = ObjectSet(
|
|
blocks = listOf(
|
|
Block(
|
|
id = MockDataFactory.randomUuid(),
|
|
children = emptyList(),
|
|
fields = Block.Fields.empty(),
|
|
content = Block.Content.DataView(
|
|
relations = listOf(relation),
|
|
viewers = listOf(viewer),
|
|
sources = listOf(
|
|
MockDataFactory.randomUuid()
|
|
)
|
|
)
|
|
)
|
|
),
|
|
// viewerDb = mapOf(
|
|
// viewer.id to ObjectSet.ViewerData(
|
|
// records = listOf(record),
|
|
// total = 1
|
|
// )
|
|
// )
|
|
)
|
|
|
|
// TESTING
|
|
|
|
launchFragment(
|
|
bundleOf(
|
|
RelationTextValueFragment.CONTEXT_ID to root,
|
|
RelationTextValueFragment.RELATION_ID to relation.key,
|
|
RelationTextValueFragment.OBJECT_ID to target,
|
|
RelationTextValueFragment.FLOW_KEY to RelationTextValueFragment.FLOW_DATAVIEW
|
|
)
|
|
)
|
|
|
|
// TESTING
|
|
|
|
onView(withId(R.id.textInputField)).apply {
|
|
check(matches(withText(valueText)))
|
|
}
|
|
|
|
onView(withId(R.id.tvRelationHeader)).apply {
|
|
check(matches(withText(relationText)))
|
|
}
|
|
|
|
onView(withId(R.id.btnAction)).apply {
|
|
check(matches(isDisplayed()))
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun shouldSetEmailTextAndDisplayActionButton() {
|
|
|
|
// SETUP
|
|
|
|
val relationText = "Email"
|
|
val valueText = "foo.bar@foobar.com"
|
|
|
|
val target = MockDataFactory.randomUuid()
|
|
|
|
val viewer = Block.Content.DataView.Viewer(
|
|
id = MockDataFactory.randomUuid(),
|
|
name = MockDataFactory.randomString(),
|
|
filters = emptyList(),
|
|
sorts = emptyList(),
|
|
viewerRelations = emptyList(),
|
|
type = Block.Content.DataView.Viewer.Type.GRID
|
|
)
|
|
|
|
val relation = Relation(
|
|
key = MockDataFactory.randomUuid(),
|
|
name = relationText,
|
|
format = Relation.Format.EMAIL,
|
|
source = Relation.Source.values().random()
|
|
)
|
|
|
|
val record: Map<String, Any?> = mapOf(
|
|
ObjectSetConfig.ID_KEY to target,
|
|
relation.key to valueText
|
|
)
|
|
|
|
state.value = ObjectSet(
|
|
blocks = listOf(
|
|
Block(
|
|
id = MockDataFactory.randomUuid(),
|
|
children = emptyList(),
|
|
fields = Block.Fields.empty(),
|
|
content = Block.Content.DataView(
|
|
relations = listOf(relation),
|
|
viewers = listOf(viewer),
|
|
sources = listOf(
|
|
MockDataFactory.randomUuid()
|
|
)
|
|
)
|
|
)
|
|
),
|
|
// viewerDb = mapOf(
|
|
// viewer.id to ObjectSet.ViewerData(
|
|
// records = listOf(record),
|
|
// total = 1
|
|
// )
|
|
// )
|
|
)
|
|
|
|
launchFragment(
|
|
bundleOf(
|
|
RelationTextValueFragment.CONTEXT_ID to root,
|
|
RelationTextValueFragment.RELATION_ID to relation.key,
|
|
RelationTextValueFragment.OBJECT_ID to target,
|
|
RelationTextValueFragment.FLOW_KEY to RelationTextValueFragment.FLOW_DATAVIEW
|
|
)
|
|
)
|
|
|
|
// TESTING
|
|
|
|
onView(withId(R.id.textInputField)).apply {
|
|
check(matches(withText(valueText)))
|
|
}
|
|
|
|
onView(withId(R.id.tvRelationHeader)).apply {
|
|
check(matches(withText(relationText)))
|
|
}
|
|
|
|
onView(withId(R.id.btnAction)).apply {
|
|
check(matches(isDisplayed()))
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun shouldSetUrlTextAndDisplayActionButton() {
|
|
|
|
// SETUP
|
|
|
|
val relationText = "Url"
|
|
val valueText = "https://anytype.io"
|
|
|
|
val target = MockDataFactory.randomUuid()
|
|
|
|
val viewer = Block.Content.DataView.Viewer(
|
|
id = MockDataFactory.randomUuid(),
|
|
name = MockDataFactory.randomString(),
|
|
filters = emptyList(),
|
|
sorts = emptyList(),
|
|
viewerRelations = emptyList(),
|
|
type = Block.Content.DataView.Viewer.Type.GRID
|
|
)
|
|
|
|
val relation = Relation(
|
|
key = MockDataFactory.randomUuid(),
|
|
name = relationText,
|
|
format = Relation.Format.URL,
|
|
source = Relation.Source.values().random()
|
|
)
|
|
|
|
val record: Map<String, Any?> = mapOf(
|
|
ObjectSetConfig.ID_KEY to target,
|
|
relation.key to valueText
|
|
)
|
|
|
|
state.value = ObjectSet(
|
|
blocks = listOf(
|
|
Block(
|
|
id = MockDataFactory.randomUuid(),
|
|
children = emptyList(),
|
|
fields = Block.Fields.empty(),
|
|
content = Block.Content.DataView(
|
|
relations = listOf(relation),
|
|
viewers = listOf(viewer),
|
|
sources = listOf(
|
|
MockDataFactory.randomUuid()
|
|
)
|
|
)
|
|
)
|
|
),
|
|
// viewerDb = mapOf(
|
|
// viewer.id to ObjectSet.ViewerData(
|
|
// records = listOf(record),
|
|
// total = 1
|
|
// )
|
|
// )
|
|
)
|
|
|
|
launchFragment(
|
|
bundleOf(
|
|
RelationTextValueFragment.CONTEXT_ID to root,
|
|
RelationTextValueFragment.RELATION_ID to relation.key,
|
|
RelationTextValueFragment.OBJECT_ID to target,
|
|
RelationTextValueFragment.FLOW_KEY to RelationTextValueFragment.FLOW_DATAVIEW
|
|
)
|
|
)
|
|
|
|
// TESTING
|
|
|
|
onView(withId(R.id.textInputField)).apply {
|
|
check(matches(withText(valueText)))
|
|
}
|
|
|
|
onView(withId(R.id.tvRelationHeader)).apply {
|
|
check(matches(withText(relationText)))
|
|
}
|
|
|
|
onView(withId(R.id.btnAction)).apply {
|
|
check(matches(isDisplayed()))
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun shouldDisplayShortText() {
|
|
|
|
// SETUP
|
|
|
|
val relationText = "Short text"
|
|
val valueText =
|
|
"Anytype is a next generation software that breaks down barriers between applications, gives back privacy and data ownership to users."
|
|
|
|
val target = MockDataFactory.randomUuid()
|
|
|
|
val viewer = Block.Content.DataView.Viewer(
|
|
id = MockDataFactory.randomUuid(),
|
|
name = MockDataFactory.randomString(),
|
|
filters = emptyList(),
|
|
sorts = emptyList(),
|
|
viewerRelations = emptyList(),
|
|
type = Block.Content.DataView.Viewer.Type.GRID
|
|
)
|
|
|
|
val relation = Relation(
|
|
key = MockDataFactory.randomUuid(),
|
|
name = relationText,
|
|
format = Relation.Format.SHORT_TEXT,
|
|
source = Relation.Source.values().random()
|
|
)
|
|
|
|
val record: Map<String, Any?> = mapOf(
|
|
ObjectSetConfig.ID_KEY to target,
|
|
relation.key to valueText
|
|
)
|
|
|
|
state.value = ObjectSet(
|
|
blocks = listOf(
|
|
Block(
|
|
id = MockDataFactory.randomUuid(),
|
|
children = emptyList(),
|
|
fields = Block.Fields.empty(),
|
|
content = Block.Content.DataView(
|
|
relations = listOf(relation),
|
|
viewers = listOf(viewer),
|
|
sources = listOf(
|
|
MockDataFactory.randomUuid()
|
|
)
|
|
)
|
|
)
|
|
),
|
|
// viewerDb = mapOf(
|
|
// viewer.id to ObjectSet.ViewerData(
|
|
// records = listOf(record),
|
|
// total = 1
|
|
// )
|
|
// )
|
|
)
|
|
|
|
launchFragment(
|
|
bundleOf(
|
|
RelationTextValueFragment.CONTEXT_ID to root,
|
|
RelationTextValueFragment.RELATION_ID to relation.key,
|
|
RelationTextValueFragment.OBJECT_ID to target,
|
|
RelationTextValueFragment.FLOW_KEY to RelationTextValueFragment.FLOW_DATAVIEW
|
|
)
|
|
)
|
|
|
|
// TESTING
|
|
|
|
onView(withId(R.id.textInputField)).apply {
|
|
check(matches(withText(valueText)))
|
|
check(matches(withInputType(InputType.TYPE_CLASS_TEXT)))
|
|
check(matches(TextLineCountMatcher(1)))
|
|
}
|
|
|
|
onView(withId(R.id.tvRelationHeader)).apply {
|
|
check(matches(withText(relationText)))
|
|
}
|
|
|
|
onView(withId(R.id.btnAction)).apply {
|
|
check(matches(not(isDisplayed())))
|
|
}
|
|
}
|
|
|
|
private fun launchFragment(args: Bundle): FragmentScenario<TestRelationTextValueFragment> {
|
|
return launchFragmentInContainer(
|
|
fragmentArgs = args,
|
|
themeResId = R.style.AppTheme
|
|
)
|
|
}
|
|
} |