extracting settings view model fixtures to their parent modules

This commit is contained in:
Adam Brown 2022-03-06 14:22:32 +00:00
parent 4dc89091ba
commit 5485ec3b84
19 changed files with 158 additions and 79 deletions

View File

@ -0,0 +1,8 @@
package fake
import io.mockk.mockk
import java.io.InputStream
class FakeInputStream {
val instance = mockk<InputStream>()
}

View File

@ -0,0 +1,20 @@
plugins {
id 'kotlin'
id 'java-test-fixtures'
}
def properties = new Properties()
def localProperties = rootProject.file("local.properties")
if (localProperties.exists()) {
properties.load(rootProject.file("local.properties").newDataInputStream())
} else {
properties.setProperty("sdk.dir", System.getenv("ANDROID_HOME"))
}
dependencies {
def androidVer = 31
kotlinFixtures(it)
testFixturesImplementation testFixtures(project(":core"))
testFixturesImplementation files("${properties.getProperty("sdk.dir")}/platforms/android-${androidVer}/android.jar")
}

View File

@ -0,0 +1,16 @@
package fake
import android.content.ContentResolver
import android.net.Uri
import io.mockk.every
import io.mockk.mockk
import test.delegateReturn
class FakeContentResolver {
val instance = mockk<ContentResolver>()
fun givenFile(uri: Uri) = every { instance.openInputStream(uri) }.delegateReturn()
fun givenUriResult(uri: Uri) = every { instance.query(uri, null, null, null, null) }.delegateReturn()
}

View File

@ -1,4 +1,4 @@
package app.dapk.st.settings package fake
import android.database.Cursor import android.database.Cursor
import io.mockk.every import io.mockk.every

View File

@ -0,0 +1,18 @@
package fake
import android.net.Uri
import io.mockk.every
import io.mockk.mockk
class FakeUri {
val instance = mockk<Uri>()
fun givenNonHierarchical() {
givenContent(schema = "mail", path = null)
}
fun givenContent(schema: String, path: String?) {
every { instance.scheme } returns schema
every { instance.path } returns path
}
}

View File

@ -2,6 +2,7 @@ plugins {
id 'kotlin' id 'kotlin'
id 'com.squareup.sqldelight' id 'com.squareup.sqldelight'
id 'org.jetbrains.kotlin.plugin.serialization' id 'org.jetbrains.kotlin.plugin.serialization'
id 'java-test-fixtures'
} }
sqldelight { sqldelight {
@ -22,4 +23,6 @@ dependencies {
implementation Dependencies.mavenCentral.kotlinSerializationJson implementation Dependencies.mavenCentral.kotlinSerializationJson
implementation Dependencies.mavenCentral.kotlinCoroutinesCore implementation Dependencies.mavenCentral.kotlinCoroutinesCore
implementation "com.squareup.sqldelight:coroutines-extensions:1.5.3" implementation "com.squareup.sqldelight:coroutines-extensions:1.5.3"
kotlinFixtures(it)
} }

View File

@ -0,0 +1,6 @@
package fixture
import app.dapk.st.domain.StoreCleaner
import io.mockk.mockk
class FakeStoreCleaner : StoreCleaner by mockk()

View File

@ -12,7 +12,11 @@ dependencies {
kotlinTest(it) kotlinTest(it)
androidImportFixturesWorkaround(project, project(":matrix:services:sync"))
androidImportFixturesWorkaround(project, project(":matrix:services:crypto"))
androidImportFixturesWorkaround(project, project(":matrix:common")) androidImportFixturesWorkaround(project, project(":matrix:common"))
androidImportFixturesWorkaround(project, project(":core")) androidImportFixturesWorkaround(project, project(":core"))
androidImportFixturesWorkaround(project, project(":domains:store"))
androidImportFixturesWorkaround(project, project(":domains:android:viewmodel")) androidImportFixturesWorkaround(project, project(":domains:android:viewmodel"))
androidImportFixturesWorkaround(project, project(":domains:android:stub"))
} }

View File

@ -5,11 +5,11 @@ import app.dapk.st.core.Lce
import app.dapk.st.design.components.Route import app.dapk.st.design.components.Route
import app.dapk.st.design.components.SpiderPage import app.dapk.st.design.components.SpiderPage
data class SettingsScreenState( internal data class SettingsScreenState(
val page: SpiderPage<out Page>, val page: SpiderPage<out Page>,
) )
sealed interface Page { internal sealed interface Page {
data class Root(val content: Lce<List<SettingItem>>) : Page data class Root(val content: Lce<List<SettingItem>>) : Page
object Security : Page object Security : Page
data class ImportRoomKey( data class ImportRoomKey(
@ -29,7 +29,7 @@ data class NamedUri(
val uri: Uri, val uri: Uri,
) )
sealed interface SettingItem { internal sealed interface SettingItem {
val id: Id val id: Id

View File

@ -1,6 +1,8 @@
package app.dapk.st.settings package app.dapk.st.settings
import app.dapk.st.core.BuildMeta import app.dapk.st.core.BuildMeta
import internalfixture.aSettingHeaderItem
import internalfixture.aSettingTextItem
import org.amshove.kluent.shouldBeEqualTo import org.amshove.kluent.shouldBeEqualTo
import org.junit.Test import org.junit.Test

View File

@ -1,22 +1,16 @@
package app.dapk.st.settings package app.dapk.st.settings
import ViewModelTest import ViewModelTest
import android.content.ContentResolver
import android.database.Cursor
import android.net.Uri
import app.dapk.st.core.Lce import app.dapk.st.core.Lce
import app.dapk.st.design.components.SpiderPage import app.dapk.st.design.components.SpiderPage
import app.dapk.st.domain.StoreCleaner import fake.*
import app.dapk.st.matrix.crypto.CryptoService import fixture.FakeStoreCleaner
import app.dapk.st.matrix.sync.SyncService
import fake.FakeCredentialsStore
import fixture.aRoomId import fixture.aRoomId
import io.mockk.coEvery import internalfake.FakeSettingsItemFactory
import io.mockk.every import internalfake.FakeUriFilenameResolver
import io.mockk.mockk import internalfixture.aImportRoomKeysPage
import internalfixture.aSettingTextItem
import org.junit.Test import org.junit.Test
import test.delegateReturn
import java.io.InputStream
private const val APP_PRIVACY_POLICY_URL = "https://ouchadam.github.io/small-talk/privacy/" private const val APP_PRIVACY_POLICY_URL = "https://ouchadam.github.io/small-talk/privacy/"
private val A_LIST_OF_ROOT_ITEMS = listOf(aSettingTextItem()) private val A_LIST_OF_ROOT_ITEMS = listOf(aSettingTextItem())
@ -203,71 +197,8 @@ internal class SettingsViewModelTest {
} }
class FakeInputStream {
val instance = mockk<InputStream>()
}
fun aSettingTextItem(
id: SettingItem.Id = SettingItem.Id.Ignored,
content: String = "text-content",
subtitle: String? = null
) = SettingItem.Text(id, content, subtitle)
fun aSettingHeaderItem(
label: String = "header-label",
) = SettingItem.Header(label)
class FakeContentResolver {
val instance = mockk<ContentResolver>()
fun givenFile(uri: Uri) = every { instance.openInputStream(uri) }.delegateReturn()
fun givenUriResult(uri: Uri) = every { instance.query(uri, null, null, null, null) }.delegateReturn()
}
internal class FakeSettingsItemFactory {
val instance = mockk<SettingsItemFactory>()
fun givenRoot() = every { instance.root() }.delegateReturn()
}
class FakeStoreCleaner : StoreCleaner by mockk()
class FakeCryptoService : CryptoService by mockk() {
fun givenImportKeys(inputStream: InputStream, passphrase: String) = coEvery { inputStream.importRoomKeys(passphrase) }.delegateReturn()
}
class FakeSyncService : SyncService by mockk()
class FakeUriFilenameResolver {
val instance = mockk<UriFilenameResolver>()
fun givenFilename(uri: Uri) = coEvery { instance.readFilenameFromUri(uri) }
}
class FakeUri {
val instance = mockk<Uri>()
fun givenNonHierarchical() {
givenContent(schema = "mail", path = null)
}
fun givenContent(schema: String, path: String?) {
every { instance.scheme } returns schema
every { instance.path } returns path
}
}
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
private inline fun <reified S : Page> SpiderPage<out Page>.updateState(crossinline block: S.() -> S): SpiderPage<Page> { private inline fun <reified S : Page> SpiderPage<out Page>.updateState(crossinline block: S.() -> S): SpiderPage<Page> {
require(this.state is S) require(this.state is S)
return (this as SpiderPage<S>).copy(state = block(this.state)) as SpiderPage<Page> return (this as SpiderPage<S>).copy(state = block(this.state)) as SpiderPage<Page>
} }
fun aImportRoomKeysPage(
state: Page.ImportRoomKey = Page.ImportRoomKey()
) = SpiderPage(
route = Page.Routes.importRoomKeys,
label = "Import room keys",
parent = Page.Routes.encryption,
state = state
)

View File

@ -2,6 +2,9 @@ package app.dapk.st.settings
import android.provider.OpenableColumns import android.provider.OpenableColumns
import app.dapk.st.core.CoroutineDispatchers import app.dapk.st.core.CoroutineDispatchers
import fake.FakeContentResolver
import fake.FakeCursor
import fake.FakeUri
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.amshove.kluent.shouldBeEqualTo import org.amshove.kluent.shouldBeEqualTo
import org.junit.Test import org.junit.Test

View File

@ -0,0 +1,12 @@
package internalfake
import app.dapk.st.settings.SettingsItemFactory
import io.mockk.every
import io.mockk.mockk
import test.delegateReturn
internal class FakeSettingsItemFactory {
val instance = mockk<SettingsItemFactory>()
fun givenRoot() = every { instance.root() }.delegateReturn()
}

View File

@ -0,0 +1,12 @@
package internalfake
import android.net.Uri
import app.dapk.st.settings.UriFilenameResolver
import io.mockk.coEvery
import io.mockk.mockk
class FakeUriFilenameResolver {
val instance = mockk<UriFilenameResolver>()
fun givenFilename(uri: Uri) = coEvery { instance.readFilenameFromUri(uri) }
}

View File

@ -0,0 +1,13 @@
package internalfixture
import app.dapk.st.design.components.SpiderPage
import app.dapk.st.settings.Page
internal fun aImportRoomKeysPage(
state: Page.ImportRoomKey = Page.ImportRoomKey()
) = SpiderPage(
route = Page.Routes.importRoomKeys,
label = "Import room keys",
parent = Page.Routes.encryption,
state = state
)

View File

@ -0,0 +1,13 @@
package internalfixture
import app.dapk.st.settings.SettingItem
internal fun aSettingTextItem(
id: SettingItem.Id = SettingItem.Id.Ignored,
content: String = "text-content",
subtitle: String? = null
) = SettingItem.Text(id, content, subtitle)
internal fun aSettingHeaderItem(
label: String = "header-label",
) = SettingItem.Header(label)

View File

@ -0,0 +1,11 @@
package fake
import app.dapk.st.matrix.crypto.CryptoService
import io.mockk.coEvery
import io.mockk.mockk
import test.delegateReturn
import java.io.InputStream
class FakeCryptoService : CryptoService by mockk() {
fun givenImportKeys(inputStream: InputStream, passphrase: String) = coEvery { inputStream.importRoomKeys(passphrase) }.delegateReturn()
}

View File

@ -0,0 +1,6 @@
package fake
import app.dapk.st.matrix.sync.SyncService
import io.mockk.mockk
class FakeSyncService : SyncService by mockk()

View File

@ -20,6 +20,7 @@ include ':features:messenger'
include ':features:navigator' include ':features:navigator'
include ':features:verification' include ':features:verification'
include ':domains:android:stub'
include ':domains:android:core' include ':domains:android:core'
include ':domains:android:imageloader' include ':domains:android:imageloader'
include ':domains:android:work' include ':domains:android:work'