diff --git a/app/src/main/java/org/thoughtcrime/securesms/net/SignalNetwork.kt b/app/src/main/java/org/thoughtcrime/securesms/net/SignalNetwork.kt index fc0efb53b0..04c45e6a26 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/net/SignalNetwork.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/net/SignalNetwork.kt @@ -29,85 +29,182 @@ import org.whispersystems.signalservice.api.storage.StorageServiceApi /** * A convenient way to access network operations, similar to [org.thoughtcrime.securesms.database.SignalDatabase] and [org.thoughtcrime.securesms.keyvalue.SignalStore]. + * + * Everything is served out of a single instance, which can be swapped out via [init] to inject custom implementations. */ -object SignalNetwork { - @JvmStatic - @get:JvmName("account") - val account: AccountApi +open class SignalNetwork { + + open val account: AccountApi get() = AppDependencies.accountApi - val accountV2: AccountApiV2 + open val accountV2: AccountApiV2 get() = AppDependencies.accountApiV2 - val archive: ArchiveApi + open val archive: ArchiveApi get() = AppDependencies.archiveApi - val archiveV2: ArchiveApiV2 + open val archiveV2: ArchiveApiV2 get() = AppDependencies.archiveApiV2 - val attachments: AttachmentApi + open val attachments: AttachmentApi get() = AppDependencies.attachmentApi - @JvmStatic - @get:JvmName("calling") - val calling: CallingApi + open val calling: CallingApi get() = AppDependencies.callingApi - val cdsApi: CdsApi + open val cdsApi: CdsApi get() = AppDependencies.cdsApi - @JvmStatic - @get:JvmName("certificate") - val certificate: CertificateApi + open val certificate: CertificateApi get() = AppDependencies.certificateApi - @JvmStatic - @get:JvmName("keys") - val keys: KeysApi + open val keys: KeysApi get() = AppDependencies.keysApi - val linkDevice: LinkDeviceApi + open val keyTransparency: KeyTransparencyApi + get() = AppDependencies.keyTransparencyApi + + open val linkDevice: LinkDeviceApi get() = AppDependencies.linkDeviceApi - @JvmStatic - @get:JvmName("message") - val message: MessageApi + open val message: MessageApi get() = AppDependencies.messageApi - @JvmStatic - @get:JvmName("payments") - val payments: PaymentsApi + open val payments: PaymentsApi get() = AppDependencies.paymentsApi - @JvmStatic - @get:JvmName("profile") - val profile: ProfileApi + open val profile: ProfileApi get() = AppDependencies.profileApi - val provisioning: ProvisioningApi + open val provisioning: ProvisioningApi get() = AppDependencies.provisioningApi - @JvmStatic - @get:JvmName("rateLimitChallenge") - val rateLimitChallenge: RateLimitChallengeApi + open val rateLimitChallenge: RateLimitChallengeApi get() = AppDependencies.rateLimitChallengeApi - @JvmStatic - @get:JvmName("remoteConfig") - val remoteConfig: RemoteConfigApi + open val remoteConfig: RemoteConfigApi get() = AppDependencies.remoteConfigApi - val storageService: StorageServiceApi + open val storageService: StorageServiceApi get() = AppDependencies.storageServiceApi - @JvmStatic - @get:JvmName("username") - val username: UsernameApi - get() = AppDependencies.usernameApi - - val svrB: SvrBApi + open val svrB: SvrBApi get() = AppDependencies.svrBApi - val keyTransparency: KeyTransparencyApi - get() = AppDependencies.keyTransparencyApi + open val username: UsernameApi + get() = AppDependencies.usernameApi + + companion object { + + private var instance: SignalNetwork = SignalNetwork() + + /** + * Swaps out the instance that serves every api. Lets us inject custom implementations, including mocks in tests. + */ + @JvmStatic + @Synchronized + fun init(instance: SignalNetwork) { + Companion.instance = instance + } + + @JvmStatic + @get:JvmName("account") + val account: AccountApi + get() = instance.account + + @JvmStatic + @get:JvmName("accountV2") + val accountV2: AccountApiV2 + get() = instance.accountV2 + + @JvmStatic + @get:JvmName("archive") + val archive: ArchiveApi + get() = instance.archive + + @JvmStatic + @get:JvmName("archiveV2") + val archiveV2: ArchiveApiV2 + get() = instance.archiveV2 + + @JvmStatic + @get:JvmName("attachments") + val attachments: AttachmentApi + get() = instance.attachments + + @JvmStatic + @get:JvmName("calling") + val calling: CallingApi + get() = instance.calling + + @JvmStatic + @get:JvmName("cdsApi") + val cdsApi: CdsApi + get() = instance.cdsApi + + @JvmStatic + @get:JvmName("certificate") + val certificate: CertificateApi + get() = instance.certificate + + @JvmStatic + @get:JvmName("keys") + val keys: KeysApi + get() = instance.keys + + @JvmStatic + @get:JvmName("keyTransparency") + val keyTransparency: KeyTransparencyApi + get() = instance.keyTransparency + + @JvmStatic + @get:JvmName("linkDevice") + val linkDevice: LinkDeviceApi + get() = instance.linkDevice + + @JvmStatic + @get:JvmName("message") + val message: MessageApi + get() = instance.message + + @JvmStatic + @get:JvmName("payments") + val payments: PaymentsApi + get() = instance.payments + + @JvmStatic + @get:JvmName("profile") + val profile: ProfileApi + get() = instance.profile + + @JvmStatic + @get:JvmName("provisioning") + val provisioning: ProvisioningApi + get() = instance.provisioning + + @JvmStatic + @get:JvmName("rateLimitChallenge") + val rateLimitChallenge: RateLimitChallengeApi + get() = instance.rateLimitChallenge + + @JvmStatic + @get:JvmName("remoteConfig") + val remoteConfig: RemoteConfigApi + get() = instance.remoteConfig + + @JvmStatic + @get:JvmName("storageService") + val storageService: StorageServiceApi + get() = instance.storageService + + @JvmStatic + @get:JvmName("svrB") + val svrB: SvrBApi + get() = instance.svrB + + @JvmStatic + @get:JvmName("username") + val username: UsernameApi + get() = instance.username + } } diff --git a/app/src/test/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceRepositoryTest.kt b/app/src/test/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceRepositoryTest.kt index fb9eaab574..ff38429bcd 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceRepositoryTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/linkdevice/LinkDeviceRepositoryTest.kt @@ -8,8 +8,6 @@ package org.thoughtcrime.securesms.linkdevice import android.app.Application import io.mockk.every import io.mockk.mockk -import io.mockk.mockkObject -import io.mockk.unmockkObject import io.mockk.verify import org.junit.After import org.junit.Assert.assertEquals @@ -41,14 +39,17 @@ class LinkDeviceRepositoryTest { @Before fun setUp() { Log.initialize(SystemOutLogger()) - mockkObject(SignalNetwork) - every { SignalNetwork.attachments } returns attachments - every { SignalNetwork.archive } returns archive + + val signalApi = mockk() + every { signalApi.attachments } returns attachments + every { signalApi.archive } returns archive + + SignalNetwork.init(signalApi) } @After fun tearDown() { - unmockkObject(SignalNetwork) + SignalNetwork.init(SignalNetwork()) } @Test diff --git a/app/src/test/java/org/thoughtcrime/securesms/testutil/FakeStorageServiceRule.kt b/app/src/test/java/org/thoughtcrime/securesms/testutil/FakeStorageServiceRule.kt index 56415beb9b..2b9ef5b27a 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/testutil/FakeStorageServiceRule.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/testutil/FakeStorageServiceRule.kt @@ -91,12 +91,14 @@ class FakeStorageServiceRule(val storageKey: StorageKey = StorageKey(Util.getSec every { api.readStorageItems(any(), any()) } answers { readStorageItems(secondArg()) } every { api.writeStorageItems(any(), any()) } answers { writeStorageItems(secondArg()) } - mockkObject(SignalNetwork) - every { SignalNetwork.storageService } returns api + val signalApi = mockk() + every { signalApi.storageService } returns api + + SignalNetwork.init(signalApi) } override fun after() { - unmockkObject(SignalNetwork) + SignalNetwork.init(SignalNetwork()) unmockkObject(RemoteConfig) }