package social.grain import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test import social.grain.data.model.ActorViewerState import social.grain.data.model.GrainProfileDetailed import social.grain.feature.profile.ProfileUiState /** * The two halves of a follow relationship are independent, and the profile * header reads both: `following` decides Follow versus Following, `followedBy` * decides the "Follows you" chip and whether the button says "Follow back". * Confusing them is easy and silently wrong in only one direction. */ class FollowRelationshipTest { private fun profileWith(following: String?, followedBy: String?) = ProfileUiState( did = "did:plc:them", viewerDid = "did:plc:me", profile = GrainProfileDetailed( did = "did:plc:them", handle = "them.test", viewer = ActorViewerState(following = following, followedBy = followedBy), ), ) @Test fun `they follow me and I do not follow back`() { val state = profileWith(following = null, followedBy = "at://follow/1") assertTrue("chip should show", state.followsViewer) assertFalse("button should offer to follow", state.isFollowing) } @Test fun `I follow them and they do not follow me`() { val state = profileWith(following = "at://follow/2", followedBy = null) assertFalse("no chip — this is one-directional", state.followsViewer) assertTrue(state.isFollowing) } @Test fun `mutual follow shows the chip and the following state`() { val state = profileWith(following = "at://follow/3", followedBy = "at://follow/4") assertTrue(state.followsViewer) assertTrue(state.isFollowing) } @Test fun `no relationship shows neither`() { val state = profileWith(following = null, followedBy = null) assertFalse(state.followsViewer) assertFalse(state.isFollowing) } @Test fun `a profile that has not loaded claims no relationship`() { val state = ProfileUiState(did = "did:plc:them", viewerDid = "did:plc:me") assertFalse(state.followsViewer) assertFalse(state.isFollowing) } }