Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
pauljohanneskraft committed Nov 28, 2024
1 parent 132f692 commit 5f3651f
Show file tree
Hide file tree
Showing 21 changed files with 353 additions and 124 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package edu.stanford.spezi.core.design.views.personalinfo

import android.annotation.SuppressLint
import kotlinx.serialization.Serializable

@SuppressLint("UnsafeOptInUsageError")
@Serializable
data class PersonNameComponents(
val namePrefix: String? = null,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,49 @@
package edu.stanford.spezi.module.account

import androidx.compose.ui.test.junit4.createAndroidComposeRule
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import edu.stanford.spezi.core.design.component.ComposeContentActivity
import edu.stanford.spezi.core.testing.onAllNodes
import edu.stanford.spezi.module.account.composables.AccountTestComposable
import edu.stanford.spezi.module.account.composables.provider.DefaultCredentials
import edu.stanford.spezi.module.account.composables.provider.TestConfiguration
import edu.stanford.spezi.module.account.composables.provider.TestConfigurationComposable
import edu.stanford.spezi.module.account.composables.provider.TestConfigurationIdentifier
import org.junit.Before
import org.junit.Rule
import org.junit.Test

@HiltAndroidTest
class AccountTest {

@get:Rule
val hiltRule = HiltAndroidRule(this)

@get:Rule
val composeTestRule = createAndroidComposeRule<ComposeContentActivity>()

@Before
fun init() {
val configuration = TestConfiguration(
credentials = DefaultCredentials.CREATE_AND_SIGN_IN
)
composeTestRule.activity.setScreen {
TestConfigurationComposable(configuration) {
AccountTestComposable()
}
}
}

@Test
fun checkAccount() {
composeTestRule.waitUntil(1_000) {
composeTestRule
.onAllNodes(TestConfigurationIdentifier.CONTENT)
.fetchSemanticsNodes().size == 1
}

println("Done")
TODO("Empty Test")
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package edu.stanford.spezi.module.account.composables

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.Color
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import edu.stanford.spezi.core.design.component.ListRow
import edu.stanford.spezi.module.account.account.Account
import edu.stanford.spezi.module.account.account.AccountOverview
import edu.stanford.spezi.module.account.account.AccountOverviewCloseBehavior
import edu.stanford.spezi.module.account.account.compositionLocal.LocalAccount
import edu.stanford.spezi.module.account.account.value.keys.accountId
import edu.stanford.spezi.module.account.account.value.keys.isAnonymous
import edu.stanford.spezi.module.account.account.value.keys.userId
import edu.stanford.spezi.module.account.utils.TestStandard
import edu.stanford.spezi.module.account.utils.invitationCode
import javax.inject.Inject

@HiltViewModel
class AccountOverviewTestViewModel @Inject constructor(
val standard: TestStandard,
val account: Account,
) : ViewModel()

@Composable
fun AccountTestComposable() {
val viewModel = hiltViewModel<AccountOverviewTestViewModel>()

CompositionLocalProvider(LocalAccount provides viewModel.account) {
Column {
Text("AccountOverviewTestComposable")
Header(
viewModel.account,
viewModel.standard,
)
OverviewSheet(viewModel.account)
}
}
}

@Composable
private fun Header(
account: Account,
standard: TestStandard,
) {
val accountIdFromAnonymousUser = remember { mutableStateOf<String?>(null) }
account.details?.let { details ->
ListRow("User Id") {
if (details.isAnonymous) {
Text("Anonymous")

LaunchedEffect(Unit) {
accountIdFromAnonymousUser.value = details.accountId
}
} else {
Text(details.userId)
}
}
accountIdFromAnonymousUser.value?.let { accountId ->
ListRow("Account Id") {
if (details.accountId == accountId) {
Text("Stable", color = Color.Green)
} else {
Text("Changed", color = Color.Red)
}
}
}
}

if (standard.deleteNotified) {
Text("Got notified about deletion!")
}
}

@Composable
private fun OverviewSheet(account: Account) {
AccountOverview(closeBehavior = AccountOverviewCloseBehavior.SHOW_CLOSE_BUTTON) {
Text("License Information")

account.details?.invitationCode?.let {
Text("Invitation Code: $it")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package edu.stanford.spezi.module.account.composables.provider

enum class AccountValueConfigurationType {
DEFAULT, ALL_REQUIRED, ALL_REQUIRED_WITH_BIO
}

enum class DefaultCredentials {
DISABLED, CREATE, CREATE_AND_SIGN_IN
}

enum class AccountServiceType {
MAIL, BOTH, WITH_IDENTITY_PROVIDER, EMPTY
}

data class TestConfiguration(
val serviceType: AccountServiceType = AccountServiceType.MAIL,
val valueConfiguration: AccountValueConfigurationType = AccountValueConfigurationType.DEFAULT,
val credentials: DefaultCredentials = DefaultCredentials.DISABLED,
val accountRequired: Boolean = false,
val noName: Boolean = false,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package edu.stanford.spezi.module.account.composables.provider

import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import edu.stanford.spezi.core.design.views.views.model.ViewState
import edu.stanford.spezi.core.design.views.views.viewstate.ViewStateAlert
import edu.stanford.spezi.core.utils.extensions.testIdentifier
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

enum class TestConfigurationIdentifier {
CONTENT,
}

@Composable
fun TestConfigurationComposable(
configuration: TestConfiguration,
content: @Composable () -> Unit,
) {
val isLoaded = remember { mutableStateOf(false) }
val viewState = remember { mutableStateOf<ViewState>(ViewState.Idle) }
val viewModel = hiltViewModel<TestConfigurationViewModel>()

LaunchedEffect(Unit) {
GlobalScope.launch {
viewState.value = ViewState.Processing
try {
viewModel.configure(configuration)
viewState.value = ViewState.Idle
isLoaded.value = true
} catch (throwable: Throwable) {
viewState.value = ViewState.Error(throwable)
}
}
}

ViewStateAlert(viewState)

if (viewState.value == ViewState.Idle && isLoaded.value) {
Box(Modifier.testIdentifier(TestConfigurationIdentifier.CONTENT)) {
content()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package edu.stanford.spezi.module.account.composables.provider

import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import edu.stanford.spezi.module.account.account.mock.InMemoryAccountService
import edu.stanford.spezi.module.account.account.value.AccountKeys
import edu.stanford.spezi.module.account.account.value.keys.name
import edu.stanford.spezi.module.account.utils.defaultAccountDetails
import javax.inject.Inject

@HiltViewModel
class TestConfigurationViewModel @Inject constructor(
private val service: InMemoryAccountService,
) : ViewModel() {
suspend fun configure(configuration: TestConfiguration) {
val details = defaultAccountDetails()
if (configuration.noName) {
details.remove(AccountKeys.name)
}
when (configuration.credentials) {
DefaultCredentials.CREATE -> {
service.signUp(details)
service.logout()
}
DefaultCredentials.CREATE_AND_SIGN_IN -> {
service.signUp(details)
}
DefaultCredentials.DISABLED -> {
return
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package edu.stanford.spezi.module.account.composables.provider

import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import edu.stanford.spezi.core.coroutines.di.Dispatching
import edu.stanford.spezi.module.account.account.AccountConfiguration
import edu.stanford.spezi.module.account.account.mock.InMemoryAccountService
import edu.stanford.spezi.module.account.utils.TestStandard
import kotlinx.coroutines.CoroutineScope

@Module
@InstallIn(SingletonComponent::class)
class TestModule {

@Provides
fun provideStandard() = TestStandard()

@Provides
fun provideInMemoryAccountService(@Dispatching.IO scope: CoroutineScope) =
InMemoryAccountService(scope = scope)

@Provides
fun provideAccountConfiguration(service: InMemoryAccountService) =
AccountConfiguration(service = service)
}

This file was deleted.

Loading

0 comments on commit 5f3651f

Please sign in to comment.