Add unit test for RegistrationUtil.

This commit is contained in:
Cody Henthorne
2024-11-22 10:18:56 -05:00
committed by Greyson Parrelli
parent 34eef0bf5c
commit 7d24bff134
16 changed files with 356 additions and 134 deletions

View File

@@ -1,29 +1,27 @@
package org.thoughtcrime.securesms.components.emoji
import android.app.Application
import androidx.test.core.app.ApplicationProvider
import io.mockk.every
import io.mockk.mockkObject
import org.junit.Assert
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.ParameterizedRobolectricTestRunner
import org.robolectric.annotation.Config
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.dependencies.MockApplicationDependencyProvider
import org.thoughtcrime.securesms.emoji.EmojiSource
import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule
@RunWith(ParameterizedRobolectricTestRunner::class)
@Config(manifest = Config.NONE, application = Application::class)
class EmojiUtilTest_isEmoji(private val input: String?, private val output: Boolean) {
@get:Rule
val appDependencies = MockAppDependenciesRule()
@Throws(Exception::class)
@Test
fun isEmoji() {
if (!AppDependencies.isInitialized) {
AppDependencies.init(ApplicationProvider.getApplicationContext(), MockApplicationDependencyProvider())
}
val source = EmojiSource.loadAssetBasedEmojis()
mockkObject(EmojiSource) {

View File

@@ -1,7 +1,6 @@
package org.thoughtcrime.securesms.components.settings.app.account.export
import android.app.Application
import androidx.test.core.app.ApplicationProvider
import com.fasterxml.jackson.core.JsonParseException
import io.mockk.every
import io.mockk.mockk
@@ -12,14 +11,13 @@ import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertThrows
import org.junit.Assert.assertTrue
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.dependencies.AppDependencies
import org.thoughtcrime.securesms.dependencies.MockApplicationDependencyProvider
import org.thoughtcrime.securesms.providers.BlobProvider
import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule
import org.thoughtcrime.securesms.util.JsonUtils
import org.whispersystems.signalservice.api.SignalServiceAccountManager
import java.io.IOException
@@ -28,6 +26,9 @@ import java.io.IOException
@Config(manifest = Config.NONE, application = Application::class)
class ExportAccountDataTest {
@get:Rule
val appDependencies = MockAppDependenciesRule()
private val mockJson: String = """
{
"reportId": "4c0ca2aa-151b-4e9e-8bf4-ea2c64345a22",
@@ -64,13 +65,6 @@ class ExportAccountDataTest {
}
"""
@Before
fun setup() {
if (!AppDependencies.isInitialized) {
AppDependencies.init(ApplicationProvider.getApplicationContext(), MockApplicationDependencyProvider())
}
}
@Test
fun `Export json without text field`() {
val scheduler = TestScheduler()

View File

@@ -1,20 +1,19 @@
package org.thoughtcrime.securesms.crash
import android.app.Application
import androidx.test.core.app.ApplicationProvider
import io.mockk.every
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.assertIs
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.dependencies.MockApplicationDependencyProvider
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule
import org.thoughtcrime.securesms.util.RemoteConfig
import org.whispersystems.signalservice.api.push.ServiceId
import java.util.UUID
@@ -23,14 +22,13 @@ import java.util.UUID
@Config(manifest = Config.NONE, application = Application::class)
class CrashConfigTest {
@get:Rule
val appDependencies = MockAppDependenciesRule()
@Before
fun setup() {
mockkObject(RemoteConfig)
if (!AppDependencies.isInitialized) {
AppDependencies.init(ApplicationProvider.getApplicationContext(), MockApplicationDependencyProvider())
}
mockkObject(SignalStore)
every { SignalStore.account.aci } returns ServiceId.ACI.from(UUID.randomUUID())
}

View File

@@ -10,22 +10,25 @@ import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
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.conversation.colors.AvatarColor
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.dependencies.MockApplicationDependencyProvider
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.testing.TestDatabaseUtil
import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule
import java.time.DayOfWeek
@RunWith(RobolectricTestRunner::class)
@Config(manifest = Config.NONE, application = Application::class)
class NotificationProfileDatabaseTest {
@get:Rule
val appDependencies = MockAppDependenciesRule()
private lateinit var db: SQLiteDatabase
private lateinit var database: NotificationProfileDatabase
@@ -42,10 +45,6 @@ class NotificationProfileDatabaseTest {
}
}
if (!AppDependencies.isInitialized) {
AppDependencies.init(ApplicationProvider.getApplicationContext(), MockApplicationDependencyProvider())
}
db = sqlCipher.writableDatabase
database = NotificationProfileDatabase(ApplicationProvider.getApplicationContext(), sqlCipher)
}

View File

@@ -54,83 +54,83 @@ import java.util.function.Supplier
class MockApplicationDependencyProvider : AppDependencies.Provider {
override fun providePushServiceSocket(signalServiceConfiguration: SignalServiceConfiguration, groupsV2Operations: GroupsV2Operations): PushServiceSocket {
return mockk()
return mockk(relaxed = true)
}
override fun provideGroupsV2Operations(signalServiceConfiguration: SignalServiceConfiguration): GroupsV2Operations {
return mockk()
return mockk(relaxed = true)
}
override fun provideSignalServiceAccountManager(pushServiceSocket: PushServiceSocket, groupsV2Operations: GroupsV2Operations): SignalServiceAccountManager {
return mockk()
return mockk(relaxed = true)
}
override fun provideSignalServiceMessageSender(signalWebSocket: SignalWebSocket, protocolStore: SignalServiceDataStore, pushServiceSocket: PushServiceSocket): SignalServiceMessageSender {
return mockk()
return mockk(relaxed = true)
}
override fun provideSignalServiceMessageReceiver(pushServiceSocket: PushServiceSocket): SignalServiceMessageReceiver {
return mockk()
return mockk(relaxed = true)
}
override fun provideSignalServiceNetworkAccess(): SignalServiceNetworkAccess {
return mockk()
return mockk(relaxed = true)
}
override fun provideRecipientCache(): LiveRecipientCache {
return mockk()
return mockk(relaxed = true)
}
override fun provideJobManager(): JobManager {
return mockk()
return mockk(relaxed = true)
}
override fun provideFrameRateTracker(): FrameRateTracker {
return mockk()
return mockk(relaxed = true)
}
override fun provideMegaphoneRepository(): MegaphoneRepository {
return mockk()
return mockk(relaxed = true)
}
override fun provideEarlyMessageCache(): EarlyMessageCache {
return mockk()
return mockk(relaxed = true)
}
override fun provideMessageNotifier(): MessageNotifier {
return mockk()
return mockk(relaxed = true)
}
override fun provideIncomingMessageObserver(): IncomingMessageObserver {
return mockk()
return mockk(relaxed = true)
}
override fun provideTrimThreadsByDateManager(): TrimThreadsByDateManager {
return mockk()
return mockk(relaxed = true)
}
override fun provideViewOnceMessageManager(): ViewOnceMessageManager {
return mockk()
return mockk(relaxed = true)
}
override fun provideExpiringStoriesManager(): ExpiringStoriesManager {
return mockk()
return mockk(relaxed = true)
}
override fun provideExpiringMessageManager(): ExpiringMessageManager {
return mockk()
return mockk(relaxed = true)
}
override fun provideDeletedCallEventManager(): DeletedCallEventManager {
return mockk()
return mockk(relaxed = true)
}
override fun provideTypingStatusRepository(): TypingStatusRepository {
return mockk()
return mockk(relaxed = true)
}
override fun provideTypingStatusSender(): TypingStatusSender {
return mockk()
return mockk(relaxed = true)
}
override fun provideDatabaseObserver(): DatabaseObserver {
@@ -138,98 +138,98 @@ class MockApplicationDependencyProvider : AppDependencies.Provider {
}
override fun providePayments(signalServiceAccountManager: SignalServiceAccountManager): Payments {
return mockk()
return mockk(relaxed = true)
}
override fun provideShakeToReport(): ShakeToReport {
return mockk()
return mockk(relaxed = true)
}
override fun provideSignalCallManager(): SignalCallManager {
return mockk()
return mockk(relaxed = true)
}
override fun providePendingRetryReceiptManager(): PendingRetryReceiptManager {
return mockk()
return mockk(relaxed = true)
}
override fun providePendingRetryReceiptCache(): PendingRetryReceiptCache {
return mockk()
return mockk(relaxed = true)
}
override fun provideSignalWebSocket(signalServiceConfigurationSupplier: Supplier<SignalServiceConfiguration>, libSignalNetworkSupplier: Supplier<Network>): SignalWebSocket {
return mockk()
return mockk(relaxed = true)
}
override fun provideProtocolStore(): SignalServiceDataStoreImpl {
return mockk()
return mockk(relaxed = true)
}
override fun provideGiphyMp4Cache(): GiphyMp4Cache {
return mockk()
return mockk(relaxed = true)
}
override fun provideExoPlayerPool(): SimpleExoPlayerPool {
return mockk()
return mockk(relaxed = true)
}
override fun provideAndroidCallAudioManager(): AudioManagerCompat {
return mockk()
return mockk(relaxed = true)
}
override fun provideDonationsService(pushServiceSocket: PushServiceSocket): DonationsService {
return mockk()
return mockk(relaxed = true)
}
override fun provideCallLinksService(pushServiceSocket: PushServiceSocket): CallLinksService {
return mockk()
return mockk(relaxed = true)
}
override fun provideProfileService(profileOperations: ClientZkProfileOperations, signalServiceMessageReceiver: SignalServiceMessageReceiver, signalWebSocket: SignalWebSocket): ProfileService {
return mockk()
return mockk(relaxed = true)
}
override fun provideDeadlockDetector(): DeadlockDetector {
return mockk()
return mockk(relaxed = true)
}
override fun provideClientZkReceiptOperations(signalServiceConfiguration: SignalServiceConfiguration): ClientZkReceiptOperations {
return mockk()
return mockk(relaxed = true)
}
override fun provideScheduledMessageManager(): ScheduledMessageManager {
return mockk()
return mockk(relaxed = true)
}
override fun provideLibsignalNetwork(config: SignalServiceConfiguration): Network {
return mockk()
return mockk(relaxed = true)
}
override fun provideBillingApi(): BillingApi {
return mockk()
return mockk(relaxed = true)
}
override fun provideArchiveApi(pushServiceSocket: PushServiceSocket): ArchiveApi {
return mockk()
return mockk(relaxed = true)
}
override fun provideKeysApi(pushServiceSocket: PushServiceSocket): KeysApi {
return mockk()
return mockk(relaxed = true)
}
override fun provideAttachmentApi(signalWebSocket: SignalWebSocket, pushServiceSocket: PushServiceSocket): AttachmentApi {
return mockk()
return mockk(relaxed = true)
}
override fun provideLinkDeviceApi(pushServiceSocket: PushServiceSocket): LinkDeviceApi {
return mockk()
return mockk(relaxed = true)
}
override fun provideRegistrationApi(pushServiceSocket: PushServiceSocket): RegistrationApi {
return mockk()
return mockk(relaxed = true)
}
override fun provideStorageServiceApi(pushServiceSocket: PushServiceSocket): StorageServiceApi {
return mockk()
return mockk(relaxed = true)
}
}

View File

@@ -15,6 +15,7 @@ import org.hamcrest.Matchers
import org.hamcrest.Matchers.`is`
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
@@ -34,12 +35,11 @@ import org.thoughtcrime.securesms.TestZkGroupServer
import org.thoughtcrime.securesms.database.GroupStateTestData
import org.thoughtcrime.securesms.database.GroupTable
import org.thoughtcrime.securesms.database.model.databaseprotos.member
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.dependencies.MockApplicationDependencyProvider
import org.thoughtcrime.securesms.groups.v2.GroupCandidateHelper
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.logging.CustomSignalProtocolLogger
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule
import org.thoughtcrime.securesms.testutil.SystemOutLogger
import org.thoughtcrime.securesms.util.RemoteConfig
import org.whispersystems.signalservice.api.groupsv2.ClientZkOperations
@@ -68,6 +68,9 @@ class GroupManagerV2Test_edit {
val others: List<DecryptedMember> = listOf(member(otherAci))
}
@get:Rule
val appDependencies = MockAppDependenciesRule()
private lateinit var groupTable: GroupTable
private lateinit var groupsV2API: GroupsV2Api
private lateinit var groupsV2Operations: GroupsV2Operations
@@ -81,10 +84,6 @@ class GroupManagerV2Test_edit {
@Suppress("UsePropertyAccessSyntax")
@Before
fun setUp() {
if (!AppDependencies.isInitialized) {
AppDependencies.init(ApplicationProvider.getApplicationContext(), MockApplicationDependencyProvider())
}
mockkObject(RemoteConfig)
mockkObject(SignalStore)
every { RemoteConfig.internalUser } returns false

View File

@@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.groups.v2.processing
import android.annotation.SuppressLint
import android.app.Application
import androidx.test.core.app.ApplicationProvider
import io.mockk.every
import io.mockk.justRun
import io.mockk.mockk
@@ -17,6 +16,7 @@ import org.hamcrest.Matchers.hasItem
import org.hamcrest.Matchers.`is`
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
@@ -45,7 +45,6 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.requestingMember
import org.thoughtcrime.securesms.database.setNewDescription
import org.thoughtcrime.securesms.database.setNewTitle
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.dependencies.MockApplicationDependencyProvider
import org.thoughtcrime.securesms.groups.GroupId
import org.thoughtcrime.securesms.groups.GroupNotAMemberException
import org.thoughtcrime.securesms.groups.GroupsV2Authorization
@@ -57,6 +56,7 @@ import org.thoughtcrime.securesms.jobs.RequestGroupV2InfoJob
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.logging.CustomSignalProtocolLogger
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule
import org.thoughtcrime.securesms.testutil.SystemOutLogger
import org.whispersystems.signalservice.api.NetworkResult
import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupResponse
@@ -90,6 +90,9 @@ class GroupsV2StateProcessorTest {
private val others: List<DecryptedMember> = listOf(member(otherAci))
}
@get:Rule
val appDependencies = MockAppDependenciesRule()
private lateinit var groupTable: GroupTable
private lateinit var recipientTable: RecipientTable
private lateinit var threadTable: ThreadTable
@@ -103,10 +106,6 @@ class GroupsV2StateProcessorTest {
@Before
fun setUp() {
if (!AppDependencies.isInitialized) {
AppDependencies.init(ApplicationProvider.getApplicationContext(), MockApplicationDependencyProvider())
}
mockkObject(SignalStore)
every { SignalStore.internal.gv2IgnoreP2PChanges } returns false

View File

@@ -1,7 +1,6 @@
package org.thoughtcrime.securesms.keyvalue
import android.app.Application
import androidx.test.core.app.ApplicationProvider
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkObject
@@ -9,26 +8,25 @@ 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.dependencies.AppDependencies
import org.thoughtcrime.securesms.dependencies.MockApplicationDependencyProvider
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
fun setup() {
if (!AppDependencies.isInitialized) {
AppDependencies.init(ApplicationProvider.getApplicationContext(), MockApplicationDependencyProvider())
}
mockkObject(RemoteConfig)
mockkObject(SignalStore)

View File

@@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.megaphone
import android.app.Application
import android.net.Uri
import androidx.test.core.app.ApplicationProvider
import io.mockk.clearMocks
import io.mockk.every
import io.mockk.mockk
@@ -14,8 +13,8 @@ import org.hamcrest.Matchers.nullValue
import org.json.JSONObject
import org.junit.After
import org.junit.AfterClass
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
@@ -23,8 +22,7 @@ import org.robolectric.annotation.Config
import org.thoughtcrime.securesms.database.RemoteMegaphoneTable
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.RemoteMegaphoneRecord
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.dependencies.MockApplicationDependencyProvider
import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule
import org.thoughtcrime.securesms.util.toMillis
import java.time.LocalDateTime
import java.util.UUID
@@ -37,12 +35,8 @@ import java.util.UUID
@Config(manifest = Config.NONE, application = Application::class)
class RemoteMegaphoneRepositoryTest {
@Before
fun setUp() {
if (!AppDependencies.isInitialized) {
AppDependencies.init(ApplicationProvider.getApplicationContext(), MockApplicationDependencyProvider())
}
}
@get:Rule
val appDependencies = MockAppDependenciesRule()
@After
fun tearDown() {

View File

@@ -1,7 +1,6 @@
package org.thoughtcrime.securesms.notifications
import android.app.Application
import androidx.test.core.app.ApplicationProvider
import io.mockk.every
import io.mockk.mockkObject
import io.mockk.mockkStatic
@@ -9,6 +8,7 @@ import io.mockk.unmockkAll
import org.junit.After
import org.junit.Assert
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
@@ -20,13 +20,13 @@ import org.thoughtcrime.securesms.database.MessageTable.SyncMessageId
import org.thoughtcrime.securesms.database.model.MessageId
import org.thoughtcrime.securesms.database.model.StoryType
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.dependencies.MockApplicationDependencyProvider
import org.thoughtcrime.securesms.jobmanager.Job
import org.thoughtcrime.securesms.jobmanager.JobManager
import org.thoughtcrime.securesms.jobmanager.JsonJobData
import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule
import org.thoughtcrime.securesms.util.TextSecurePreferences
import java.util.LinkedList
@@ -34,17 +34,13 @@ import java.util.LinkedList
@Config(manifest = Config.NONE, application = Application::class)
class MarkReadReceiverTest {
@get:Rule
val appDependencies = MockAppDependenciesRule()
private val jobs: MutableList<Job> = LinkedList()
@Before
fun setUp() {
if (!AppDependencies.isInitialized) {
AppDependencies.init(
ApplicationProvider.getApplicationContext(),
MockApplicationDependencyProvider()
)
}
val jobManager: JobManager = AppDependencies.jobManager
every { jobManager.add(capture(jobs)) } returns Unit

View File

@@ -1,7 +1,6 @@
package org.thoughtcrime.securesms.notifications.profiles
import android.app.Application
import androidx.test.core.app.ApplicationProvider
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkObject
@@ -11,14 +10,14 @@ import org.hamcrest.Matchers.`is`
import org.hamcrest.Matchers.nullValue
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.dependencies.AppDependencies
import org.thoughtcrime.securesms.dependencies.MockApplicationDependencyProvider
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
@@ -29,6 +28,9 @@ import java.time.ZoneOffset
@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)
private val sunday930am: LocalDateTime = LocalDateTime.of(2021, 7, 4, 9, 30, 0)
@@ -55,10 +57,6 @@ class NotificationProfilesTest {
@Before
fun setUp() {
if (!AppDependencies.isInitialized) {
AppDependencies.init(ApplicationProvider.getApplicationContext(), MockApplicationDependencyProvider())
}
notificationProfileValues = mockk()
every { notificationProfileValues.manuallyEnabledUntil } returns 0
every { notificationProfileValues.manuallyDisabledAt } returns 0

View File

@@ -0,0 +1,143 @@
/*
* Copyright 2024 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.registration.util
import android.app.Application
import io.mockk.Runs
import io.mockk.every
import io.mockk.just
import io.mockk.mockkObject
import io.mockk.unmockkAll
import io.mockk.verify
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.util.logging.Log.initialize
import org.thoughtcrime.securesms.assertIs
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues
import org.thoughtcrime.securesms.profiles.ProfileName
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.testutil.LogRecorder
import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule
import org.thoughtcrime.securesms.testutil.MockSignalStoreRule
import org.thoughtcrime.securesms.util.RemoteConfig
@RunWith(RobolectricTestRunner::class)
@Config(application = Application::class, manifest = Config.NONE)
class RegistrationUtilTest {
@get:Rule
val signalStore = MockSignalStoreRule(relaxed = setOf(PhoneNumberPrivacyValues::class))
@get:Rule
val appDependencies = MockAppDependenciesRule()
private lateinit var logRecorder: LogRecorder
@Before
fun setup() {
mockkObject(Recipient)
mockkObject(RemoteConfig)
every { RemoteConfig.init() } just Runs
logRecorder = LogRecorder()
initialize(logRecorder)
}
@After
fun tearDown() {
unmockkAll()
}
@Test
fun maybeMarkRegistrationComplete_allValidNoRestoreOption() {
every { signalStore.registration.isRegistrationComplete } returns false
every { signalStore.account.isRegistered } returns true
every { Recipient.self() } returns Recipient(profileName = ProfileName.fromParts("Dark", "Helmet"))
every { signalStore.svr.hasOptedInWithAccess() } returns true
every { RemoteConfig.restoreAfterRegistration } returns false
RegistrationUtil.maybeMarkRegistrationComplete()
verify { signalStore.registration.markRegistrationComplete() }
}
@Test
fun maybeMarkRegistrationComplete_allValidNoRestoreOptionSvrOptOut() {
every { signalStore.registration.isRegistrationComplete } returns false
every { signalStore.account.isRegistered } returns true
every { Recipient.self() } returns Recipient(profileName = ProfileName.fromParts("Dark", "Helmet"))
every { signalStore.svr.hasOptedInWithAccess() } returns false
every { signalStore.svr.hasOptedOut() } returns true
every { RemoteConfig.restoreAfterRegistration } returns false
RegistrationUtil.maybeMarkRegistrationComplete()
verify { signalStore.registration.markRegistrationComplete() }
}
@Test
fun maybeMarkRegistrationComplete_allValidWithRestoreOption() {
every { signalStore.registration.isRegistrationComplete } returns false
every { signalStore.account.isRegistered } returns true
every { Recipient.self() } returns Recipient(profileName = ProfileName.fromParts("Dark", "Helmet"))
every { signalStore.svr.hasOptedInWithAccess() } returns true
every { RemoteConfig.restoreAfterRegistration } returns true
every { signalStore.registration.hasSkippedTransferOrRestore() } returns true
RegistrationUtil.maybeMarkRegistrationComplete()
verify { signalStore.registration.markRegistrationComplete() }
}
@Test
fun maybeMarkRegistrationComplete_missingData() {
every { signalStore.registration.isRegistrationComplete } returns false
every { signalStore.account.isRegistered } returns false
RegistrationUtil.maybeMarkRegistrationComplete()
every { signalStore.account.isRegistered } returns true
every { Recipient.self() } returns Recipient(profileName = ProfileName.EMPTY)
RegistrationUtil.maybeMarkRegistrationComplete()
every { Recipient.self() } returns Recipient(profileName = ProfileName.fromParts("Dark", "Helmet"))
every { signalStore.svr.hasOptedInWithAccess() } returns false
every { signalStore.svr.hasOptedOut() } returns false
RegistrationUtil.maybeMarkRegistrationComplete()
every { signalStore.svr.hasOptedInWithAccess() } returns true
every { RemoteConfig.restoreAfterRegistration } returns true
every { signalStore.registration.hasSkippedTransferOrRestore() } returns false
every { signalStore.registration.hasCompletedRestore() } returns false
RegistrationUtil.maybeMarkRegistrationComplete()
verify(exactly = 0) { signalStore.registration.markRegistrationComplete() }
val regUtilLogs = logRecorder.information.filter { it.tag == "RegistrationUtil" }
regUtilLogs.size assertIs 4
regUtilLogs.all { it.message == "Registration is not yet complete." } assertIs true
}
@Test
fun maybeMarkRegistrationComplete_alreadyMarked() {
every { signalStore.registration.isRegistrationComplete } returns true
RegistrationUtil.maybeMarkRegistrationComplete()
verify(exactly = 0) { signalStore.registration.markRegistrationComplete() }
val regUtilLogs = logRecorder.information.filter { it.tag == "RegistrationUtil" }
regUtilLogs.size assertIs 0
}
}

View File

@@ -1,7 +1,6 @@
package org.thoughtcrime.securesms.storage
import android.app.Application
import androidx.test.core.app.ApplicationProvider
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkObject
@@ -12,16 +11,16 @@ 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.util.logging.Log
import org.thoughtcrime.securesms.database.RecipientTable
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.dependencies.MockApplicationDependencyProvider
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.testutil.EmptyLogger
import org.thoughtcrime.securesms.testutil.MockAppDependenciesRule
import org.whispersystems.signalservice.api.push.ServiceId.ACI
import org.whispersystems.signalservice.api.push.ServiceId.PNI
import org.whispersystems.signalservice.api.storage.SignalContactRecord
@@ -33,14 +32,13 @@ import java.util.UUID
@Config(application = Application::class)
class ContactRecordProcessorTest {
@get:Rule
val appDependencies = MockAppDependenciesRule()
lateinit var recipientTable: RecipientTable
@Before
fun setup() {
if (!AppDependencies.isInitialized) {
AppDependencies.init(ApplicationProvider.getApplicationContext(), MockApplicationDependencyProvider())
}
mockkObject(SignalStore)
every { SignalStore.account.isPrimaryDevice } returns true

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2024 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.testutil
import androidx.test.core.app.ApplicationProvider
import io.mockk.clearMocks
import org.junit.rules.ExternalResource
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.dependencies.MockApplicationDependencyProvider
import kotlin.reflect.KVisibility
import kotlin.reflect.full.memberProperties
/**
* Facilitates mocking and clearing components of [AppDependencies]. Clearing is particularly important as the
* mocks will be reused since [AppDependencies] is scoped to the entire test suite and stays initialized with prior
* test runs leading to unpredictable results based on how tests are run.
*/
class MockAppDependenciesRule : ExternalResource() {
private val skipList = setOf(
"application",
"databaseObserver",
"groupsV2Authorization",
"isInitialized",
"okHttpClient",
"signalOkHttpClient",
"webSocketObserver"
)
private val properties = AppDependencies::class
.memberProperties
.filter { it.visibility == KVisibility.PUBLIC }
.filterNot { skipList.contains(it.name) }
override fun before() {
if (!AppDependencies.isInitialized) {
AppDependencies.init(ApplicationProvider.getApplicationContext(), MockApplicationDependencyProvider())
}
}
override fun after() {
properties
.forEach { property ->
property.get(AppDependencies)?.let { clearMocks(it) }
}
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2024 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.testutil
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkObject
import io.mockk.unmockkObject
import org.junit.rules.ExternalResource
import org.thoughtcrime.securesms.keyvalue.AccountValues
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues
import org.thoughtcrime.securesms.keyvalue.RegistrationValues
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.keyvalue.SvrValues
import kotlin.reflect.KClass
/**
* Mocks [SignalStore] to return mock versions of the various values. Mocks will default to not be relaxed (each
* method call on them will need to be mocked) except for unit functions which will do nothing.
*
* Expand mocked values as necessary when needed.
*
* @param relaxed Set of value classes that should default to relaxed thus defaulting all methods. Useful
* when value is not part of the input state under test but called within the under test code.
*/
@Suppress("MemberVisibilityCanBePrivate")
class MockSignalStoreRule(private val relaxed: Set<KClass<*>> = emptySet()) : ExternalResource() {
lateinit var account: AccountValues
private set
lateinit var phoneNumberPrivacy: PhoneNumberPrivacyValues
private set
lateinit var registration: RegistrationValues
private set
lateinit var svr: SvrValues
private set
override fun before() {
account = mockk(relaxed = relaxed.contains(AccountValues::class), relaxUnitFun = true)
phoneNumberPrivacy = mockk(relaxed = relaxed.contains(PhoneNumberPrivacyValues::class), relaxUnitFun = true)
registration = mockk(relaxed = relaxed.contains(RegistrationValues::class), relaxUnitFun = true)
svr = mockk(relaxed = relaxed.contains(SvrValues::class), relaxUnitFun = true)
mockkObject(SignalStore)
every { SignalStore.account } returns account
every { SignalStore.phoneNumberPrivacy } returns phoneNumberPrivacy
every { SignalStore.registration } returns registration
every { SignalStore.svr } returns svr
}
override fun after() {
unmockkObject(SignalStore)
}
}

View File

@@ -1,33 +1,31 @@
package org.thoughtcrime.securesms.util
import android.app.Application
import androidx.test.core.app.ApplicationProvider
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.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.dependencies.AppDependencies.application
import org.thoughtcrime.securesms.dependencies.MockApplicationDependencyProvider
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)
class SignalMeUtilText_parseE164FromLink(private val input: String?, private val output: String?) {
@get:Rule
val appDependencies = MockAppDependenciesRule()
@Before
fun setUp() {
if (!AppDependencies.isInitialized) {
AppDependencies.init(ApplicationProvider.getApplicationContext(), MockApplicationDependencyProvider())
}
mockkObject(SignalStore)
every { SignalStore.account.e164 } returns "+15555555555"
}