From aaa7a1819001faeef7e69fc8c50f0deac6d562e6 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Mon, 8 Jun 2026 11:32:41 -0400 Subject: [PATCH] Remove Robolectric from some tests with light mocking. --- .../card/CreditCardCodeValidatorTest.kt | 26 ++++++++++++++----- .../card/CreditCardExpirationValidatorTest.kt | 26 ++++++++++++++----- .../card/CreditCardNumberValidatorTest.kt | 26 ++++++++++++++----- .../securesms/crash/CrashConfigTest.kt | 11 -------- .../jobs/InAppPaymentRedemptionJobTest.kt | 6 ----- .../securesms/keyvalue/PaymentsValuesTest.kt | 11 -------- .../profiles/NotificationProfilesTest.kt | 10 ------- .../reactions/ReactionsViewModelTest.kt | 6 ----- .../service/MessageBackupListenerTest.kt | 19 ++++++-------- .../storage/ContactRecordProcessorTest.kt | 11 -------- .../viewer/StoryViewerViewModelTest.kt | 10 +++---- .../SignalMeUtilText_parseE164FromLink.kt | 14 +++------- 12 files changed, 75 insertions(+), 101 deletions(-) diff --git a/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/card/CreditCardCodeValidatorTest.kt b/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/card/CreditCardCodeValidatorTest.kt index b9a1376e1f..ea44e00d69 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/card/CreditCardCodeValidatorTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/card/CreditCardCodeValidatorTest.kt @@ -1,14 +1,17 @@ package org.thoughtcrime.securesms.components.settings.app.subscription.donate.card -import android.app.Application +import android.text.TextUtils +import io.mockk.every +import io.mockk.mockkStatic +import io.mockk.unmockkStatic +import org.junit.After import org.junit.Assert.assertEquals +import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.robolectric.ParameterizedRobolectricTestRunner -import org.robolectric.annotation.Config +import org.junit.runners.Parameterized -@RunWith(ParameterizedRobolectricTestRunner::class) -@Config(application = Application::class) +@RunWith(Parameterized::class) class CreditCardCodeValidatorTest( private val code: String, private val cardType: CreditCardType, @@ -16,6 +19,17 @@ class CreditCardCodeValidatorTest( private val validity: CreditCardCodeValidator.Validity ) { + @Before + fun setUp() { + mockkStatic(TextUtils::class) + every { TextUtils.isDigitsOnly(any()) } answers { firstArg().all { it.isDigit() } } + } + + @After + fun tearDown() { + unmockkStatic(TextUtils::class) + } + @Test fun getValidity() { assertEquals(validity, CreditCardCodeValidator.getValidity(code, cardType, isFocused)) @@ -23,7 +37,7 @@ class CreditCardCodeValidatorTest( companion object { @JvmStatic - @ParameterizedRobolectricTestRunner.Parameters(name = "{index}: getValidity(..) = {0}, {1}, {2}, {3}") + @Parameterized.Parameters(name = "{index}: getValidity(..) = {0}, {1}, {2}, {3}") fun data(): Iterable> = arrayListOf( // Unfocused arrayOf("", CreditCardType.UNIONPAY, false, CreditCardCodeValidator.Validity.POTENTIALLY_VALID), diff --git a/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/card/CreditCardExpirationValidatorTest.kt b/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/card/CreditCardExpirationValidatorTest.kt index e88c05110b..fcbb0335e9 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/card/CreditCardExpirationValidatorTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/card/CreditCardExpirationValidatorTest.kt @@ -1,14 +1,17 @@ package org.thoughtcrime.securesms.components.settings.app.subscription.donate.card -import android.app.Application +import android.text.TextUtils +import io.mockk.every +import io.mockk.mockkStatic +import io.mockk.unmockkStatic +import org.junit.After import org.junit.Assert.assertEquals +import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.robolectric.ParameterizedRobolectricTestRunner -import org.robolectric.annotation.Config +import org.junit.runners.Parameterized -@RunWith(ParameterizedRobolectricTestRunner::class) -@Config(application = Application::class) +@RunWith(Parameterized::class) class CreditCardExpirationValidatorTest( private val creditCardExpiration: CreditCardExpiration, private val currentYear: Int, @@ -16,6 +19,17 @@ class CreditCardExpirationValidatorTest( private val validity: CreditCardExpirationValidator.Validity ) { + @Before + fun setUp() { + mockkStatic(TextUtils::class) + every { TextUtils.isDigitsOnly(any()) } answers { firstArg().all { it.isDigit() } } + } + + @After + fun tearDown() { + unmockkStatic(TextUtils::class) + } + @Test fun getValidity() { assertEquals(validity, CreditCardExpirationValidator.getValidity(creditCardExpiration, 3, currentYear, isFocused)) @@ -23,7 +37,7 @@ class CreditCardExpirationValidatorTest( companion object { @JvmStatic - @ParameterizedRobolectricTestRunner.Parameters(name = "{index}: getValidity(..) = {0}, {1}, {2}, {3}, {4}") + @Parameterized.Parameters(name = "{index}: getValidity(..) = {0}, {1}, {2}, {3}, {4}") fun data(): Iterable> = arrayListOf( // Unfocused arrayOf(CreditCardExpiration("", ""), 2020, false, CreditCardExpirationValidator.Validity.POTENTIALLY_VALID), diff --git a/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/card/CreditCardNumberValidatorTest.kt b/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/card/CreditCardNumberValidatorTest.kt index 1884387035..4ba17be83c 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/card/CreditCardNumberValidatorTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/subscription/donate/card/CreditCardNumberValidatorTest.kt @@ -1,20 +1,34 @@ package org.thoughtcrime.securesms.components.settings.app.subscription.donate.card -import android.app.Application +import android.text.TextUtils +import io.mockk.every +import io.mockk.mockkStatic +import io.mockk.unmockkStatic +import org.junit.After import org.junit.Assert.assertEquals +import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.robolectric.ParameterizedRobolectricTestRunner -import org.robolectric.annotation.Config +import org.junit.runners.Parameterized -@RunWith(ParameterizedRobolectricTestRunner::class) -@Config(application = Application::class) +@RunWith(Parameterized::class) class CreditCardNumberValidatorTest( private val creditCardNumber: String, private val creditCardNumberFieldFocused: Boolean, private val validity: CreditCardNumberValidator.Validity ) { + @Before + fun setUp() { + mockkStatic(TextUtils::class) + every { TextUtils.isDigitsOnly(any()) } answers { firstArg().all { it.isDigit() } } + } + + @After + fun tearDown() { + unmockkStatic(TextUtils::class) + } + @Test fun getValidity() { assertEquals(validity, CreditCardNumberValidator.getValidity(creditCardNumber, creditCardNumberFieldFocused)) @@ -22,7 +36,7 @@ class CreditCardNumberValidatorTest( companion object { @JvmStatic - @ParameterizedRobolectricTestRunner.Parameters(name = "{index}: getValidity(..) = {0}, {1}, {2}") + @Parameterized.Parameters(name = "{index}: getValidity(..) = {0}, {1}, {2}") fun data(): Iterable> = arrayListOf( arrayOf("", false, CreditCardNumberValidator.Validity.POTENTIALLY_VALID), arrayOf("4", false, CreditCardNumberValidator.Validity.POTENTIALLY_VALID), diff --git a/app/src/test/java/org/thoughtcrime/securesms/crash/CrashConfigTest.kt b/app/src/test/java/org/thoughtcrime/securesms/crash/CrashConfigTest.kt index ddc817bc7f..97ce66a4ab 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/crash/CrashConfigTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/crash/CrashConfigTest.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.crash -import android.app.Application import assertk.assertThat import assertk.assertions.containsExactly import assertk.assertions.isEmpty @@ -9,23 +8,13 @@ import io.mockk.mockkObject import io.mockk.unmockkAll import org.junit.After import org.junit.Before -import org.junit.Rule import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config import org.signal.core.models.ServiceId import org.thoughtcrime.securesms.keyvalue.SignalStore -import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule import org.thoughtcrime.securesms.util.RemoteConfig import java.util.UUID -@RunWith(RobolectricTestRunner::class) -@Config(manifest = Config.NONE, application = Application::class) class CrashConfigTest { - @get:Rule - val appDependencies = MockAppDependenciesRule() - @Before fun setup() { mockkObject(RemoteConfig) diff --git a/app/src/test/java/org/thoughtcrime/securesms/jobs/InAppPaymentRedemptionJobTest.kt b/app/src/test/java/org/thoughtcrime/securesms/jobs/InAppPaymentRedemptionJobTest.kt index bbc10208d2..8920db4065 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/jobs/InAppPaymentRedemptionJobTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/jobs/InAppPaymentRedemptionJobTest.kt @@ -5,19 +5,13 @@ package org.thoughtcrime.securesms.jobs -import android.app.Application import assertk.assertThat import assertk.assertions.isTrue import io.mockk.every import org.junit.Rule import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config import org.thoughtcrime.securesms.testutil.MockSignalStoreRule -@RunWith(RobolectricTestRunner::class) -@Config(manifest = Config.NONE, application = Application::class) class InAppPaymentRedemptionJobTest { @get:Rule diff --git a/app/src/test/java/org/thoughtcrime/securesms/keyvalue/PaymentsValuesTest.kt b/app/src/test/java/org/thoughtcrime/securesms/keyvalue/PaymentsValuesTest.kt index 0460bef5c8..b3be92f2b0 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/keyvalue/PaymentsValuesTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/keyvalue/PaymentsValuesTest.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.keyvalue -import android.app.Application import io.mockk.every import io.mockk.mockk import io.mockk.mockkObject @@ -8,21 +7,11 @@ import io.mockk.unmockkAll import org.junit.After import org.junit.Assert.assertEquals import org.junit.Before -import org.junit.Rule import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config -import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule import org.thoughtcrime.securesms.util.RemoteConfig -@RunWith(RobolectricTestRunner::class) -@Config(manifest = Config.NONE, application = Application::class) class PaymentsValuesTest { - @get:Rule - val appDependencies = MockAppDependenciesRule() - private lateinit var paymentValues: PaymentsValues @Before diff --git a/app/src/test/java/org/thoughtcrime/securesms/notifications/profiles/NotificationProfilesTest.kt b/app/src/test/java/org/thoughtcrime/securesms/notifications/profiles/NotificationProfilesTest.kt index 6da6152490..36020ec11d 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/notifications/profiles/NotificationProfilesTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/notifications/profiles/NotificationProfilesTest.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.notifications.profiles -import android.app.Application import assertk.assertThat import assertk.assertions.isEqualTo import assertk.assertions.isNull @@ -10,25 +9,16 @@ import io.mockk.mockkObject import io.mockk.unmockkAll import org.junit.After import org.junit.Before -import org.junit.Rule import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config import org.thoughtcrime.securesms.keyvalue.NotificationProfileValues import org.thoughtcrime.securesms.keyvalue.SignalStore -import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule import org.thoughtcrime.securesms.util.toMillis import java.time.DayOfWeek import java.time.LocalDateTime import java.time.ZoneId import java.time.ZoneOffset -@RunWith(RobolectricTestRunner::class) -@Config(manifest = Config.NONE, application = Application::class) class NotificationProfilesTest { - @get:Rule - val appDependencies = MockAppDependenciesRule() private val sunday830am: LocalDateTime = LocalDateTime.of(2021, 7, 4, 8, 30, 0) private val sunday9am: LocalDateTime = LocalDateTime.of(2021, 7, 4, 9, 0, 0) diff --git a/app/src/test/java/org/thoughtcrime/securesms/reactions/ReactionsViewModelTest.kt b/app/src/test/java/org/thoughtcrime/securesms/reactions/ReactionsViewModelTest.kt index 56bb4867f2..1f26736007 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/reactions/ReactionsViewModelTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/reactions/ReactionsViewModelTest.kt @@ -5,7 +5,6 @@ package org.thoughtcrime.securesms.reactions -import android.app.Application import io.mockk.every import io.mockk.just import io.mockk.mockk @@ -16,13 +15,8 @@ import io.reactivex.rxjava3.schedulers.TestScheduler import org.junit.After import org.junit.Before import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config import org.thoughtcrime.securesms.database.model.MessageId -@RunWith(RobolectricTestRunner::class) -@Config(manifest = Config.NONE, application = Application::class) class ReactionsViewModelTest { private val testScheduler = TestScheduler() diff --git a/app/src/test/java/org/thoughtcrime/securesms/service/MessageBackupListenerTest.kt b/app/src/test/java/org/thoughtcrime/securesms/service/MessageBackupListenerTest.kt index 942a595c4b..f7368fb3f4 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/service/MessageBackupListenerTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/service/MessageBackupListenerTest.kt @@ -5,22 +5,19 @@ package org.thoughtcrime.securesms.service -import android.app.Application -import androidx.test.core.app.ApplicationProvider +import android.content.Context import assertk.assertThat import assertk.assertions.isEqualTo import assertk.assertions.isGreaterThan import assertk.assertions.isLessThan import io.mockk.every import io.mockk.just +import io.mockk.mockk import io.mockk.runs import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Rule import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.testutil.MockRandom import org.thoughtcrime.securesms.testutil.MockSignalStoreRule @@ -33,35 +30,35 @@ import kotlin.time.Duration.Companion.days import kotlin.time.Duration.Companion.hours import kotlin.time.Duration.Companion.minutes -@RunWith(RobolectricTestRunner::class) -@Config(manifest = Config.NONE, application = Application::class) class MessageBackupListenerTest { @get:Rule val rule = MockSignalStoreRule() + private val context = mockk(relaxed = true) + @Test fun testGetNextScheduledExecutionTime() { val listener = MessageBackupListener() var nextTime = System.currentTimeMillis() + 1.days.inWholeMilliseconds every { SignalStore.backup.nextBackupTime } returns nextTime - assertThat(listener.getNextScheduledExecutionTime(ApplicationProvider.getApplicationContext())).isEqualTo(nextTime) + assertThat(listener.getNextScheduledExecutionTime(context)).isEqualTo(nextTime) nextTime = System.currentTimeMillis() + 2.days.inWholeMilliseconds every { SignalStore.backup.nextBackupTime } returns nextTime - assertThat(listener.getNextScheduledExecutionTime(ApplicationProvider.getApplicationContext())).isEqualTo(nextTime) + assertThat(listener.getNextScheduledExecutionTime(context)).isEqualTo(nextTime) nextTime = System.currentTimeMillis() + 8.hours.inWholeMilliseconds every { SignalStore.backup.nextBackupTime } returns nextTime - assertThat(listener.getNextScheduledExecutionTime(ApplicationProvider.getApplicationContext())).isEqualTo(nextTime) + assertThat(listener.getNextScheduledExecutionTime(context)).isEqualTo(nextTime) nextTime = System.currentTimeMillis() + 7.days.inWholeMilliseconds every { SignalStore.backup.nextBackupTime } returns nextTime every { SignalStore.settings.signalBackupHour } returns 2 every { SignalStore.settings.signalBackupMinute } returns 0 every { SignalStore.backup.nextBackupTime = any() } just runs - val adjustedTime = listener.getNextScheduledExecutionTime(ApplicationProvider.getApplicationContext()) + val adjustedTime = listener.getNextScheduledExecutionTime(context) assertThat(adjustedTime).isGreaterThan(System.currentTimeMillis()) assertThat(adjustedTime).isLessThan(System.currentTimeMillis() + 2.days.inWholeMilliseconds) } diff --git a/app/src/test/java/org/thoughtcrime/securesms/storage/ContactRecordProcessorTest.kt b/app/src/test/java/org/thoughtcrime/securesms/storage/ContactRecordProcessorTest.kt index 3c3d33086f..2f16d17781 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/storage/ContactRecordProcessorTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/storage/ContactRecordProcessorTest.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.storage -import android.app.Application import io.mockk.every import io.mockk.mockk import io.mockk.mockkObject @@ -11,11 +10,7 @@ import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Before import org.junit.BeforeClass -import org.junit.Rule import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config import org.signal.core.models.ServiceId import org.signal.core.models.ServiceId.ACI import org.signal.core.models.ServiceId.PNI @@ -23,19 +18,13 @@ import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.database.RecipientTable import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.testutil.EmptyLogger -import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule import org.whispersystems.signalservice.api.storage.SignalContactRecord import org.whispersystems.signalservice.api.storage.StorageId import org.whispersystems.signalservice.internal.storage.protos.ContactRecord import java.util.UUID -@RunWith(RobolectricTestRunner::class) -@Config(application = Application::class) class ContactRecordProcessorTest { - @get:Rule - val appDependencies = MockAppDependenciesRule() - lateinit var recipientTable: RecipientTable @Before diff --git a/app/src/test/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerViewModelTest.kt b/app/src/test/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerViewModelTest.kt index 38e9a55600..4c493230bd 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerViewModelTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerViewModelTest.kt @@ -1,9 +1,9 @@ package org.thoughtcrime.securesms.stories.viewer -import android.app.Application import io.mockk.every import io.mockk.mockk import io.mockk.verify +import io.reactivex.rxjava3.android.plugins.RxAndroidPlugins import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.plugins.RxJavaPlugins import io.reactivex.rxjava3.schedulers.TestScheduler @@ -11,14 +11,9 @@ import org.junit.After import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.stories.StoryViewerArgs -@RunWith(RobolectricTestRunner::class) -@Config(manifest = Config.NONE, application = Application::class) class StoryViewerViewModelTest { private val testScheduler = TestScheduler() private val repository = mockk() @@ -27,6 +22,8 @@ class StoryViewerViewModelTest { fun setUp() { RxJavaPlugins.setInitComputationSchedulerHandler { testScheduler } RxJavaPlugins.setComputationSchedulerHandler { testScheduler } + RxAndroidPlugins.setInitMainThreadSchedulerHandler { testScheduler } + RxAndroidPlugins.setMainThreadSchedulerHandler { testScheduler } every { repository.getFirstStory(any(), any()) } returns Single.just(mockk()) } @@ -34,6 +31,7 @@ class StoryViewerViewModelTest { @After fun tearDown() { RxJavaPlugins.reset() + RxAndroidPlugins.reset() } @Test diff --git a/app/src/test/java/org/thoughtcrime/securesms/util/SignalMeUtilText_parseE164FromLink.kt b/app/src/test/java/org/thoughtcrime/securesms/util/SignalMeUtilText_parseE164FromLink.kt index 2ff1e74081..c5261127fd 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/util/SignalMeUtilText_parseE164FromLink.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/util/SignalMeUtilText_parseE164FromLink.kt @@ -1,28 +1,20 @@ package org.thoughtcrime.securesms.util -import android.app.Application import io.mockk.every import io.mockk.mockkObject import io.mockk.unmockkAll import org.junit.After import org.junit.Assert.assertEquals import org.junit.Before -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.robolectric.ParameterizedRobolectricTestRunner -import org.robolectric.annotation.Config +import org.junit.runners.Parameterized import org.thoughtcrime.securesms.keyvalue.SignalStore -import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule import org.thoughtcrime.securesms.util.SignalMeUtil.parseE164FromLink -@RunWith(ParameterizedRobolectricTestRunner::class) -@Config(manifest = Config.NONE, application = Application::class) +@RunWith(Parameterized::class) class SignalMeUtilText_parseE164FromLink(private val input: String?, private val output: String?) { - @get:Rule - val appDependencies = MockAppDependenciesRule() - @Before fun setUp() { mockkObject(SignalStore) @@ -41,7 +33,7 @@ class SignalMeUtilText_parseE164FromLink(private val input: String?, private val companion object { @JvmStatic - @ParameterizedRobolectricTestRunner.Parameters + @Parameterized.Parameters fun data(): Collection> { return listOf( arrayOf("https://signal.me/#p/+15555555555", "+15555555555"),