Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add flag to filter out archived conversations when fetching list [WPB-4432] #2082

Merged
merged 12 commits into from
Sep 26, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ internal class ConversationDataSource internal constructor(

override suspend fun observeConversationListDetails(includeArchived: Boolean): Flow<List<ConversationDetails>> =
combine(
conversationDAO.getAllConversationDetails(),
conversationDAO.getAllConversationDetails(includeArchived),
messageDAO.observeLastMessages(),
messageDAO.observeConversationsUnreadEvents(),
) { conversationList, lastMessageList, unreadEvents ->
Expand All @@ -420,8 +420,6 @@ internal class ConversationDataSource internal constructor(
}
}
)
}.filter {
includeArchived || !it.conversation.archived
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1232,7 +1232,7 @@ class ConversationRepositoryTest {
fun withConversations(conversations: List<ConversationViewEntity>) = apply {
given(conversationDAO)
.suspendFunction(conversationDAO::getAllConversationDetails)
.whenInvoked()
.whenInvokedWith(any())
.thenReturn(flowOf(conversations))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ WHERE
OR (type IS 'ONE_ON_ONE' AND userDeleted = 1) -- show deleted 1:1 convos, to maintain prev, logic
)
AND (protocol IS 'PROTEUS' OR (protocol IS 'MLS' AND mls_group_state IS 'ESTABLISHED'))
AND (archived = ? OR archived IS NULL)
ORDER BY lastModifiedDate DESC, name IS NULL, name COLLATE NOCASE ASC;

selectAllConversations:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ interface ConversationDAO {
suspend fun updateConversationReadDate(conversationID: QualifiedIDEntity, date: Instant)
suspend fun updateAllConversationsNotificationDate()
suspend fun getAllConversations(): Flow<List<ConversationViewEntity>>
suspend fun getAllConversationDetails(): Flow<List<ConversationViewEntity>>
suspend fun getAllConversationDetails(includeArchived: Boolean): Flow<List<ConversationViewEntity>>
suspend fun observeGetConversationByQualifiedID(qualifiedID: QualifiedIDEntity): Flow<ConversationViewEntity?>
suspend fun observeGetConversationBaseInfoByQualifiedID(qualifiedID: QualifiedIDEntity): Flow<ConversationEntity?>
suspend fun getConversationBaseInfoByQualifiedID(qualifiedID: QualifiedIDEntity): ConversationEntity?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ internal class ConversationDAOImpl internal constructor(
.map { it.map(conversationMapper::toModel) }
}

override suspend fun getAllConversationDetails(): Flow<List<ConversationViewEntity>> {
return conversationQueries.selectAllConversationDetails()
override suspend fun getAllConversationDetails(includeArchived: Boolean): Flow<List<ConversationViewEntity>> {
return conversationQueries.selectAllConversationDetails(includeArchived)
.asFlow()
.mapToList()
.flowOn(coroutineContext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,7 @@ class ConversationDAOTest : BaseDatabaseTest() {

@Test
fun givenConnectionRequestAndUserWithName_whenSelectingAllConversationDetails_thenShouldReturnConnectionRequest() = runTest {
val includeArchived = false
val conversationId = QualifiedIDEntity("connection-conversationId", "domain")
val conversation = conversationEntity1.copy(id = conversationId, type = ConversationEntity.Type.CONNECTION_PENDING)
val connectionEntity = ConnectionEntity(
Expand All @@ -809,7 +810,7 @@ class ConversationDAOTest : BaseDatabaseTest() {
conversationDAO.insertConversation(conversation)
connectionDAO.insertConnection(connectionEntity)

conversationDAO.getAllConversationDetails().first().let {
conversationDAO.getAllConversationDetails(includeArchived).first().let {
assertEquals(1, it.size)
val result = it.first()

Expand All @@ -820,6 +821,7 @@ class ConversationDAOTest : BaseDatabaseTest() {

@Test
fun givenConnectionRequestAndUserWithoutName_whenSelectingAllConversationDetails_thenShouldReturnConnectionRequest() = runTest {
val includeArchived = false
val conversationId = QualifiedIDEntity("connection-conversationId", "domain")
val conversation = conversationEntity1.copy(id = conversationId, type = ConversationEntity.Type.CONNECTION_PENDING)
val connectionEntity = ConnectionEntity(
Expand All @@ -836,13 +838,14 @@ class ConversationDAOTest : BaseDatabaseTest() {
conversationDAO.insertConversation(conversation)
connectionDAO.insertConnection(connectionEntity)

conversationDAO.getAllConversationDetails().first().let {
conversationDAO.getAllConversationDetails(includeArchived).first().let {
assertEquals(0, it.size)
}
}

@Test
fun givenLocalConversations_whenGettingAllConversations_thenShouldReturnsOnlyConversationsWithMetadata() = runTest {
val includeArchived = false
conversationDAO.insertConversation(conversationEntity1)
conversationDAO.insertConversation(conversationEntity2)

Expand All @@ -852,7 +855,7 @@ class ConversationDAOTest : BaseDatabaseTest() {
memberDAO.insertMember(member1, conversationEntity1.id)
memberDAO.insertMember(member2, conversationEntity1.id)

conversationDAO.getAllConversationDetails().first().let {
conversationDAO.getAllConversationDetails(includeArchived).first().let {
assertEquals(1, it.size)
assertEquals(conversationEntity1.id, it.first().id)
}
Expand All @@ -861,12 +864,13 @@ class ConversationDAOTest : BaseDatabaseTest() {
@Test
fun givenObserveConversationList_whenAConversationHaveNullAsName_thenItIsIncluded() = runTest {
// given
val includeArchived = false
val conversation = conversationEntity1.copy(name = null, type = ConversationEntity.Type.GROUP, hasIncompleteMetadata = false)
conversationDAO.insertConversation(conversation)
insertTeamUserAndMember(team, user1, conversation.id)

// when
val result = conversationDAO.getAllConversationDetails().first()
val result = conversationDAO.getAllConversationDetails(includeArchived).first()

// then
assertEquals(conversation.toViewEntity(user1), result.firstOrNull { it.id == conversation.id })
Expand All @@ -875,20 +879,22 @@ class ConversationDAOTest : BaseDatabaseTest() {
@Test
fun givenObserveConversationList_whenAConversationHaveIncompleteMetadata_thenItIsNotIncluded() = runTest {
// given
val includeArchived = false
val conversation = conversationEntity1.copy(hasIncompleteMetadata = true)
conversationDAO.insertConversation(conversation)
insertTeamUserAndMember(team, user1, conversation.id)

// when
val result = conversationDAO.getAllConversationDetails().first()
val result = conversationDAO.getAllConversationDetails(includeArchived).first()

// then
assertNull(result.firstOrNull { it.id == conversation.id })
}

@Test
fun givenConversaions_whenObservingTheFullList_thenConvWithNullNameAreLast() = runTest {
fun givenConversations_whenObservingTheFullList_thenConvWithNullNameAreLast() = runTest {
// given
val includeArchived = false
val conversation1 = conversationEntity1.copy(
id = ConversationIDEntity("convNullName", "domain"),
name = null,
Expand All @@ -910,13 +916,48 @@ class ConversationDAOTest : BaseDatabaseTest() {
insertTeamUserAndMember(team, user1, conversation2.id)

// when
val result = conversationDAO.getAllConversationDetails().first()
val result = conversationDAO.getAllConversationDetails(includeArchived).first()

// then
assertEquals(conversation2.id, result[0].id)
assertEquals(conversation1.id, result[1].id)
}

@Test
fun givenArchivedConversations_whenObservingTheFullListWithNoArchived_thenReturnedConversationsShouldNotBeArchived() = runTest {
// given
val includeArchived = false
val conversation1 = conversationEntity1.copy(
id = ConversationIDEntity("convNullName", "domain"),
name = null,
type = ConversationEntity.Type.GROUP,
hasIncompleteMetadata = false,
lastModifiedDate = "2021-03-30T15:36:00.000Z".toInstant(),
archived = true
)

val conversation2 = conversationEntity2.copy(
id = ConversationIDEntity("convWithName", "domain"),
name = "name",
type = ConversationEntity.Type.GROUP,
hasIncompleteMetadata = false,
lastModifiedDate = "2021-03-30T15:36:00.000Z".toInstant(),
archived = false
)
conversationDAO.insertConversation(conversation1)
conversationDAO.insertConversation(conversation2)
insertTeamUserAndMember(team, user1, conversation1.id)
insertTeamUserAndMember(team, user1, conversation2.id)

// when
val result = conversationDAO.getAllConversationDetails(includeArchived).first()

// then
assertTrue(result.size == 1)
assertTrue(!result[0].archived)
assertEquals(conversation2.id, result[0].id)
}

private suspend fun insertTeamUserAndMember(team: TeamEntity, user: UserEntity, conversationId: QualifiedIDEntity) {
teamDAO.insertTeam(team)
userDAO.insertUser(user)
Expand Down