Add 1 day after read test

This commit is contained in:
andrew
2023-09-20 00:41:34 +09:30
parent a7111b0d49
commit 92cae9adde
4 changed files with 213 additions and 159 deletions

View File

@@ -1,132 +1,188 @@
package org.thoughtcrime.securesms.conversation.expiration
import android.app.Application
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runTest
import network.loki.messenger.R
import network.loki.messenger.libsession_util.util.ExpiryMode
import org.hamcrest.CoreMatchers
import org.hamcrest.MatcherAssert
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.mock
import org.mockito.junit.MockitoJUnitRunner
import org.mockito.kotlin.whenever
import org.session.libsession.messaging.messages.ExpirationConfiguration
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.SSKEnvironment
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.utilities.guava.Optional
import org.thoughtcrime.securesms.MainCoroutineRule
import org.thoughtcrime.securesms.database.GroupDatabase
import org.thoughtcrime.securesms.database.Storage
import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.ui.GetString
import kotlin.time.Duration.Companion.hours
import network.loki.messenger.R
import kotlin.reflect.typeOf
import kotlin.time.Duration
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.hours
private const val THREAD_ID = 1L
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(MockitoJUnitRunner::class)
class ExpirationSettingsViewModelTest {
@ExperimentalCoroutinesApi
@get:Rule
var mainCoroutineRule = MainCoroutineRule()
private val application: Application = mock(Application::class.java)
private val textSecurePreferences: TextSecurePreferences = mock(TextSecurePreferences::class.java)
private val messageExpirationManager: SSKEnvironment.MessageExpirationManagerProtocol = mock(SSKEnvironment.MessageExpirationManagerProtocol::class.java)
private val threadDb: ThreadDatabase = mock(ThreadDatabase::class.java)
private val groupDb: GroupDatabase = mock(GroupDatabase::class.java)
private val storage: Storage = mock(Storage::class.java)
private val recipient = mock(Recipient::class.java)
@Mock lateinit var application: Application
@Mock lateinit var textSecurePreferences: TextSecurePreferences
@Mock lateinit var messageExpirationManager: SSKEnvironment.MessageExpirationManagerProtocol
@Mock lateinit var threadDb: ThreadDatabase
@Mock lateinit var groupDb: GroupDatabase
@Mock lateinit var storage: Storage
@Mock lateinit var recipient: Recipient
@Test
fun `UI should show a list of times and an Off option`() = runTest {
val threadId = 1L
val expirationConfig = ExpirationConfiguration(
threadId = threadId,
expiryMode = ExpiryMode.AfterSend(12.hours.inWholeSeconds),
updatedTimestampMs = 0
)
whenever(threadDb.getRecipientForThreadId(Mockito.anyLong())).thenReturn(recipient)
whenever(storage.getExpirationConfiguration(Mockito.anyLong())).thenReturn(expirationConfig)
whenever(textSecurePreferences.getLocalNumber()).thenReturn("05---LOCAL---ADDRESS")
val userAddress = Address.fromSerialized(textSecurePreferences.getLocalNumber()!!)
fun `1-1 conversation, 12 hours after send, new config`() = runTest {
val time = 12.hours
val someAddress = Address.fromSerialized("05---SOME---ADDRESS")
val config = newExpirationConfiguration(time)
whenever(threadDb.getRecipientForThreadId(Mockito.anyLong())).thenReturn(recipient)
whenever(storage.getExpirationConfiguration(Mockito.anyLong())).thenReturn(config)
whenever(textSecurePreferences.getLocalNumber()).thenReturn("05---LOCAL---ADDRESS")
whenever(recipient.isClosedGroupRecipient).thenReturn(false)
whenever(recipient.address).thenReturn(someAddress)
whenever(groupDb.getGroup(Mockito.anyString())).thenReturn(Optional.absent())
val viewModel = createViewModel()
advanceUntilIdle()
MatcherAssert.assertThat(
viewModel.state.value,
CoreMatchers.equalTo(
State(
isGroup = false,
isSelfAdmin = true,
address = someAddress,
isNoteToSelf = false,
expiryMode = ExpiryMode.AfterSend(12.hours.inWholeSeconds),
isNewConfigEnabled = true,
persistedMode = ExpiryMode.AfterSend(12.hours.inWholeSeconds),
showDebugOptions = false
assertThat(
viewModel.state.value
).isEqualTo(
State(
isGroup = false,
isSelfAdmin = true,
address = someAddress,
isNoteToSelf = false,
expiryMode = ExpiryMode.AfterSend(12.hours.inWholeSeconds),
isNewConfigEnabled = true,
persistedMode = ExpiryMode.AfterSend(12.hours.inWholeSeconds),
showDebugOptions = false
)
)
val newTypeOption = TypeOptionCreator(time)
val newTimeOption = TimeOptionCreator(ExpiryType.AFTER_SEND)
assertThat(
viewModel.uiState.value
).isEqualTo(
UiState(
showGroupFooter = false,
CardModel(
R.string.activity_expiration_settings_delete_type,
newTypeOption(ExpiryType.NONE),
newTypeOption(ExpiryType.AFTER_READ),
newTypeOption(ExpiryType.AFTER_SEND, selected = true)
),
CardModel(
GetString(R.string.activity_expiration_settings_timer),
newTimeOption(duration = 12.hours, selected = true),
newTimeOption(duration = 1.days),
newTimeOption(duration = 7.days),
newTimeOption(duration = 14.days)
)
)
)
}
val uiState = viewModel.uiState.value
@Test
fun `1-1 conversation, 1 day after send, new config`() = runTest {
val time = 1.days
val someAddress = Address.fromSerialized("05---SOME---ADDRESS")
val config = newExpirationConfiguration(time)
MatcherAssert.assertThat(
uiState.cards.map { it.title },
CoreMatchers.equalTo(
listOf(
whenever(threadDb.getRecipientForThreadId(Mockito.anyLong())).thenReturn(recipient)
whenever(storage.getExpirationConfiguration(Mockito.anyLong())).thenReturn(config)
whenever(textSecurePreferences.getLocalNumber()).thenReturn("05---LOCAL---ADDRESS")
whenever(recipient.isClosedGroupRecipient).thenReturn(false)
whenever(recipient.address).thenReturn(someAddress)
val viewModel = createViewModel()
advanceUntilIdle()
assertThat(
viewModel.state.value
).isEqualTo(
State(
isGroup = false,
isSelfAdmin = true,
address = someAddress,
isNoteToSelf = false,
expiryMode = ExpiryMode.AfterSend(1.days.inWholeSeconds),
isNewConfigEnabled = true,
persistedMode = ExpiryMode.AfterSend(1.days.inWholeSeconds),
showDebugOptions = false
)
)
val newTypeOption = TypeOptionCreator(time)
val newTimeOption = TimeOptionCreator(ExpiryType.AFTER_SEND)
assertThat(
viewModel.uiState.value
).isEqualTo(
UiState(
showGroupFooter = false,
CardModel(
R.string.activity_expiration_settings_delete_type,
R.string.activity_expiration_settings_timer
).map(::GetString)
newTypeOption(ExpiryType.NONE),
typeOption(12.hours, ExpiryType.AFTER_READ),
newTypeOption(ExpiryType.AFTER_SEND, selected = true)
),
CardModel(
GetString(R.string.activity_expiration_settings_timer),
newTimeOption(duration = 12.hours),
newTimeOption(duration = 1.days, selected = true),
newTimeOption(duration = 7.days),
newTimeOption(duration = 14.days)
)
)
)
}
MatcherAssert.assertThat(
uiState.cards[0].options.map { it.title },
CoreMatchers.equalTo(
listOf(
R.string.expiration_off,
R.string.expiration_type_disappear_after_read,
R.string.expiration_type_disappear_after_send,
).map(::GetString)
)
)
private fun newExpirationConfiguration(time: Duration) = ExpirationConfiguration(
threadId = THREAD_ID,
expiryMode = ExpiryMode.AfterSend(time.inWholeSeconds),
updatedTimestampMs = 0
)
MatcherAssert.assertThat(
uiState.cards[1].options.map { it.title },
CoreMatchers.equalTo(
listOf(
12.hours,
1.days,
7.days,
14.days,
).map(::GetString)
)
)
private class TypeOptionCreator(private val time: Duration) {
operator fun invoke(type: ExpiryType, selected: Boolean = false, enabled: Boolean = true) =
typeOption(time, type, selected, enabled)
}
MatcherAssert.assertThat(
uiState.showGroupFooter,
CoreMatchers.equalTo(false)
private class TimeOptionCreator(private val type: ExpiryType) {
operator fun invoke(duration: Duration, selected: Boolean = false, enabled: Boolean = true) = OptionModel(
value = type.mode(duration),
title = GetString(duration),
enabled = enabled,
selected = selected
)
}
private fun createViewModel(isNewConfigEnabled: Boolean = true) = ExpirationSettingsViewModel(
1L,
THREAD_ID,
application,
textSecurePreferences,
messageExpirationManager,
@@ -134,6 +190,16 @@ class ExpirationSettingsViewModelTest {
groupDb,
storage,
isNewConfigEnabled,
false
showDebugOptions = false
)
}
fun typeOption(time: Duration, type: ExpiryType, selected: Boolean = false, enabled: Boolean = true) =
OptionModel(
type.mode(time),
GetString(type.title),
type.subtitle?.let(::GetString),
GetString(type.contentDescription),
selected = selected,
enabled = enabled
)