Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,15 @@ internal class DatabaseChannelConfigRepository(
* Writes many [ChannelConfig]
*/
override suspend fun insertChannelConfigs(configs: Collection<ChannelConfig>) {
// Channel configs are keyed by type, so a page of same-type channels yields many configs
// that collapse to one row. Dedup by type to avoid the redundant per-row writes.
val configsByType = configs.associateBy(ChannelConfig::type)

// update the local configs
channelConfigs += configs.associateBy(ChannelConfig::type)
channelConfigs += configsByType

// insert into room db
channelConfigDao.insert(configs.map(ChannelConfig::toEntity))
channelConfigDao.insert(configsByType.values.map(ChannelConfig::toEntity))
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ internal class DatabaseUserRepository(
override suspend fun insertUsers(users: Collection<User>) {
if (users.isEmpty()) return
val usersToInsert = users
// Use associateBy instead of distinctBy to keep the *last* occurrence of each user
.associateBy(User::id)
.values
.filter { it != userCache[it.id] }
.map { it.toEntity() }
cacheUsers(users)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,25 @@ internal class ChannelConfigRepositoryTest {
)
}

@Test
fun `When insert configs with duplicate types Should dedup keeping the last per type`() = runTest {
val first = randomChannelConfig(type = "messaging", config = randomConfig(name = "first"))
val last = randomChannelConfig(type = "messaging", config = randomConfig(name = "last"))
val other = randomChannelConfig(type = "livestream", config = randomConfig(name = "other"))

sut.insertChannelConfigs(listOf(first, other, last))

verify(dao).insert(
argThat<List<ChannelConfigEntity>> {
size == 2 &&
single { it.channelConfigInnerEntity.channelType == "messaging" }
.channelConfigInnerEntity.name == "last" &&
single { it.channelConfigInnerEntity.channelType == "livestream" }
.channelConfigInnerEntity.name == "other"
},
)
}

@Test
fun `Given config in cache When select Should return config`() = runTest {
val config = randomChannelConfig(type = "messaging", config = randomConfig(name = "configName"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.times
Expand Down Expand Up @@ -133,6 +134,21 @@ internal class UserRepositoryTests {
verify(userDao, never()).insertMany(any())
}

@Test
fun `When insert users with duplicate ids Should insert each user only once keeping the last`() = runTest {
val id = randomString()
val firstCopy = randomUser(id = id, name = "first")
val lastCopy = firstCopy.copy(name = "last")
val other = randomUser()

sut.insertUsers(listOf(firstCopy, other, lastCopy))

val captor = argumentCaptor<List<UserEntity>>()
verify(userDao).insertMany(captor.capture())
captor.firstValue.map(UserEntity::id) shouldBeEqualTo listOf(id, other.id)
captor.firstValue.first { it.id == id }.name shouldBeEqualTo "last"
}

@Test
fun `When insert current user Should insert entity with me id to dao`() = runTest {
val user = randomUser(
Expand Down
Loading