Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Registration Flow to Remove Consent Screen and Anonymous Login and move Invitation Code screen #105

Draft
wants to merge 22 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d8f5689
navigate to LoginScreen after onboarding
Basler182 Sep 15, 2024
eefdd4b
removed is already registered login param
Basler182 Sep 15, 2024
213b2ff
adjusted InvitationCodeScreen removed AlreadySignedUp
Basler182 Sep 15, 2024
aaff800
removed already registered account navigation event param
Basler182 Sep 15, 2024
a4076b7
adjusted user sessions manager to check if invitation code was set
Basler182 Sep 15, 2024
548ae14
adjusted user state to invitation code submission
Basler182 Sep 15, 2024
78cfd33
removed is already signed up
Basler182 Sep 15, 2024
6d530f5
removed is already signed up
Basler182 Sep 15, 2024
a408912
fixed LoginViewModelTest
Basler182 Sep 15, 2024
1aa7953
fixed MainActivityViewModelTest
Basler182 Sep 20, 2024
73e6ee8
fixed SymptomsUiStateMapperTest
Basler182 Sep 20, 2024
2b5ebd0
fixed UserSessionManagerTest
Basler182 Sep 20, 2024
9acad62
fixed detekt
Basler182 Sep 20, 2024
8bc5b6a
Merge branch 'main' into update/invitation-code-flow
Basler182 Sep 20, 2024
525206b
updated and extended InvitationCodeViewModelTest
Basler182 Sep 20, 2024
b321b5b
fixed NavigatorSimulator
Basler182 Sep 20, 2024
7e1a501
fixed OnboardingFlowTest
Basler182 Sep 20, 2024
95db803
removed anonymous login in invitation code screen
Basler182 Sep 21, 2024
674833a
extracted String resources in LoginViewModel
Basler182 Sep 21, 2024
cfac58f
extracted String Resources in LoginScreen
Basler182 Sep 21, 2024
e86f224
extracted String Resources in RegisterScreen
Basler182 Sep 21, 2024
d681b0e
extracted String Resources in RegisterScreen
Basler182 Sep 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package edu.stanford.bdh.engagehf
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import edu.stanford.bdh.engagehf.simulator.NavigatorSimulator
import edu.stanford.bdh.engagehf.simulator.OnboardingFlowSimulator
import edu.stanford.spezi.core.navigation.Navigator
import edu.stanford.spezi.module.onboarding.invitation.InvitationCodeRepository
import edu.stanford.spezi.module.onboarding.onboarding.OnboardingRepository
import edu.stanford.spezi.module.onboarding.sequential.SequentialOnboardingRepository
Expand Down Expand Up @@ -31,6 +33,9 @@ class OnboardingFlowTest {
@Inject
lateinit var invitationCodeRepository: InvitationCodeRepository

@Inject
lateinit var navigator: Navigator

@Before
fun init() {
hiltRule.inject()
Expand Down Expand Up @@ -58,7 +63,8 @@ class OnboardingFlowTest {

@Test
fun `it should navigate and display sequential onboarding correctly`() = runTest {
val stepTitle = sequentialOnboardingRepository.getSequentialOnboardingData().steps.first().title
val stepTitle =
sequentialOnboardingRepository.getSequentialOnboardingData().steps.first().title
onboardingFlow {
onboardingScreen {
clickContinueButton()
Expand All @@ -73,7 +79,7 @@ class OnboardingFlowTest {
}

@Test
fun `it should display and navigate invitation screen correctly`() = runTest {
fun `it should display and navigate login screen correctly`() = runTest {
val steps = sequentialOnboardingRepository.getSequentialOnboardingData().steps
onboardingFlow {
onboardingScreen {
Expand All @@ -86,18 +92,17 @@ class OnboardingFlowTest {
}
}

invitationCodeScreen {
val screenData = invitationCodeRepository.getScreenData()
assertTitle(text = screenData.title)
assertDescription(text = screenData.description)
assertIsDisplayed()
assertMainButtonDisplayed()
assertSecondaryButtonDisplayed()
navigatorSimulator {
assertLoginScreenIsDisplayed()
}
}
}

private fun onboardingFlow(scope: OnboardingFlowSimulator.() -> Unit) {
OnboardingFlowSimulator(composeTestRule).apply(scope)
}

private fun navigatorSimulator(scope: NavigatorSimulator.() -> Unit) {
NavigatorSimulator(composeTestRule, navigator).apply(scope)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class NavigatorSimulator(
}

fun navigateToLoginScreen() {
navigator.navigateTo(AccountNavigationEvent.LoginScreen(false))
navigator.navigateTo(AccountNavigationEvent.LoginScreen)
}

fun navigateToRegisterScreen() {
Expand Down
7 changes: 2 additions & 5 deletions app/src/main/kotlin/edu/stanford/bdh/engagehf/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,7 @@
}

composable<Routes.LoginScreen> {
val args = it.toRoute<Routes.LoginScreen>()
LoginScreen(isAlreadyRegistered = args.isAlreadyRegistered)
LoginScreen()

Check warning on line 123 in app/src/main/kotlin/edu/stanford/bdh/engagehf/MainActivity.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/edu/stanford/bdh/engagehf/MainActivity.kt#L123

Added line #L123 was not covered by tests
}

composable<EducationRoutes.VideoDetail>(
Expand Down Expand Up @@ -182,9 +181,7 @@
)

is AccountNavigationEvent.LoginScreen -> navHostController.navigate(
Routes.LoginScreen(
isAlreadyRegistered = event.isAlreadyRegistered
)
Routes.LoginScreen()

Check warning on line 184 in app/src/main/kotlin/edu/stanford/bdh/engagehf/MainActivity.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/edu/stanford/bdh/engagehf/MainActivity.kt#L184

Added line #L184 was not covered by tests
)

is OnboardingNavigationEvent.InvitationCodeScreen -> navHostController.navigate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class MainActivityViewModel @Inject constructor(
val startDestination = when (val userState = userSessionManager.getUserState()) {
is UserState.NotInitialized, UserState.Anonymous -> Routes.OnboardingScreen
is UserState.Registered -> {
if (userState.hasConsented) Routes.AppScreen else Routes.ConsentScreen
if (userState.hasInvitationCodeConfirmed) Routes.AppScreen else Routes.InvitationCodeScreen
}
}
_uiState.update { MainUiState.Content(startDestination = startDestination) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package edu.stanford.bdh.engagehf.onboarding

import edu.stanford.bdh.engagehf.navigation.AppNavigationEvent
import edu.stanford.spezi.core.navigation.Navigator
import edu.stanford.spezi.module.account.AccountNavigationEvent
import edu.stanford.spezi.module.onboarding.invitation.InvitationCodeRepository
import edu.stanford.spezi.module.onboarding.invitation.InvitationCodeScreenData
import javax.inject.Inject
Expand All @@ -18,8 +18,7 @@
return InvitationCodeScreenData(
title = "Invitation Code",
description = "Please enter your invitation code to join the ENGAGE-HF study.",
redeemAction = { navigator.navigateTo(AccountNavigationEvent.LoginScreen(false)) },
gotAnAccountAction = { navigator.navigateTo(AccountNavigationEvent.LoginScreen(true)) }
redeemAction = { navigator.navigateTo(AppNavigationEvent.AppScreen) },

Check warning on line 21 in app/src/main/kotlin/edu/stanford/bdh/engagehf/onboarding/EngageInvitationCodeRepository.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/edu/stanford/bdh/engagehf/onboarding/EngageInvitationCodeRepository.kt#L21

Added line #L21 was not covered by tests
)
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package edu.stanford.bdh.engagehf.onboarding

import edu.stanford.spezi.core.navigation.Navigator
import edu.stanford.spezi.module.onboarding.OnboardingNavigationEvent
import edu.stanford.spezi.module.account.AccountNavigationEvent
import edu.stanford.spezi.module.onboarding.sequential.SequentialOnboardingData
import edu.stanford.spezi.module.onboarding.sequential.SequentialOnboardingRepository
import edu.stanford.spezi.module.onboarding.sequential.Step
Expand Down Expand Up @@ -45,7 +45,7 @@
),
actionText = "Start",
onAction = {
navigator.navigateTo(OnboardingNavigationEvent.InvitationCodeScreen)
navigator.navigateTo(AccountNavigationEvent.LoginScreen)

Check warning on line 48 in app/src/main/kotlin/edu/stanford/bdh/engagehf/onboarding/EngageSequentialOnboardingRepository.kt

View check run for this annotation

Codecov / codecov/patch

app/src/main/kotlin/edu/stanford/bdh/engagehf/onboarding/EngageSequentialOnboardingRepository.kt#L48

Added line #L48 was not covered by tests
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ class MainActivityViewModelTest {
}

@Test
fun `it should have app screen start destination for registered user if consented`() =
fun `it should have app screen start destination for registered user if has Invitation Code Confirmed`() =
runTestUnconfined {
// given
val userState = UserState.Registered(hasConsented = true)
val userState = UserState.Registered(hasInvitationCodeConfirmed = true)
coEvery { userSessionManager.getUserState() } returns userState

// when
Expand All @@ -117,17 +117,17 @@ class MainActivityViewModelTest {
}

@Test
fun `it should have consent screen start destination for registered user if not consented`() =
fun `it should have consent screen start destination for registered user if has not Invitation Code Confirmed`() =
runTestUnconfined {
// given
val userState = UserState.Registered(hasConsented = false)
val userState = UserState.Registered(hasInvitationCodeConfirmed = false)
coEvery { userSessionManager.getUserState() } returns userState

// when
createViewModel()

// then
assertStartDestination(startDestination = Routes.ConsentScreen)
assertStartDestination(startDestination = Routes.InvitationCodeScreen)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ class SymptomsUiStateMapperTest {
// Given
val symptomScores = listOf(
createSymptomScore(day = 1, overallScore = 50.0, physicalLimitsScore = 40.0),
createSymptomScore(day = 2, overallScore = 60.0, physicalLimitsScore = 50.0)
)

// When
Expand All @@ -74,8 +73,8 @@ class SymptomsUiStateMapperTest {
val successStateOverall = resultOverall as SymptomsUiState.Success
val successStatePhysical = resultPhysical as SymptomsUiState.Success

assertThat(successStateOverall.data.headerData.formattedValue).isEqualTo("60.0%")
assertThat(successStatePhysical.data.headerData.formattedValue).isEqualTo("50.0%")
assertThat(successStateOverall.data.headerData.formattedValue).isEqualTo("50.0%")
assertThat(successStatePhysical.data.headerData.formattedValue).isEqualTo("40.0%")
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
val password: String = "",
) : AccountNavigationEvent()

data class LoginScreen(val isAlreadyRegistered: Boolean) : AccountNavigationEvent()
data object LoginScreen : AccountNavigationEvent()

Check warning on line 12 in modules/account/src/main/kotlin/edu/stanford/spezi/module/account/AccountNavigationEvent.kt

View check run for this annotation

Codecov / codecov/patch

modules/account/src/main/kotlin/edu/stanford/spezi/module/account/AccountNavigationEvent.kt#L12

Added line #L12 was not covered by tests
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
Expand All @@ -42,26 +43,25 @@
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import edu.stanford.spezi.core.design.component.AsyncTextButton
import edu.stanford.spezi.core.design.component.VerticalSpacer
import edu.stanford.spezi.core.design.component.validated.outlinedtextfield.ValidatedOutlinedTextField
import edu.stanford.spezi.core.design.theme.Colors
import edu.stanford.spezi.core.design.theme.Spacings
import edu.stanford.spezi.core.design.theme.SpeziTheme
import edu.stanford.spezi.core.design.theme.TextStyles.bodyLarge
import edu.stanford.spezi.core.design.theme.TextStyles.titleLarge
import edu.stanford.spezi.core.utils.extensions.testIdentifier
import edu.stanford.spezi.module.account.R
import edu.stanford.spezi.module.account.login.components.SignInWithGoogleButton
import edu.stanford.spezi.module.account.login.components.TextDivider
import edu.stanford.spezi.module.account.register.FieldState
import edu.stanford.spezi.module.account.register.IconLeadingContent
import edu.stanford.spezi.core.design.R as DesignR

@Composable
fun LoginScreen(
isAlreadyRegistered: Boolean,
) {
fun LoginScreen() {
val viewModel = hiltViewModel<LoginViewModel>()
val uiState by viewModel.uiState.collectAsState()
viewModel.onAction(Action.SetIsAlreadyRegistered(isAlreadyRegistered))

LoginScreen(
uiState = uiState, onAction = viewModel::onAction
Expand Down Expand Up @@ -94,7 +94,7 @@
verticalArrangement = Arrangement.Center
) {
Text(
text = "Your Account", style = titleLarge
text = stringResource(R.string.your_account), style = titleLarge

Check warning on line 97 in modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt

View check run for this annotation

Codecov / codecov/patch

modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt#L97

Added line #L97 was not covered by tests
)
Spacer(modifier = Modifier.height(Spacings.large))
Text(
Expand Down Expand Up @@ -131,15 +131,15 @@
onValueChange = {
onAction(Action.TextFieldUpdate(it, TextFieldType.PASSWORD))
},
labelText = "Password",
labelText = stringResource(R.string.password),

Check warning on line 134 in modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt

View check run for this annotation

Codecov / codecov/patch

modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt#L134

Added line #L134 was not covered by tests
visualTransformation = if (uiState.passwordVisibility) {
VisualTransformation.None
} else {
PasswordVisualTransformation()
},
keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {
onAction(Action.Async.PasswordSignInOrSignUp)
onAction(Action.Async.PasswordSignIn)

Check warning on line 142 in modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt

View check run for this annotation

Codecov / codecov/patch

modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt#L142

Added line #L142 was not covered by tests
}),
trailingIcon = {
IconButton(onClick = { onAction(Action.TogglePasswordVisibility) }) {
Expand All @@ -150,15 +150,21 @@
}
Icon(
painter = painterResource(id = iconId),
contentDescription = if (uiState.passwordVisibility) "Hide password" else "Show password"
contentDescription = if (uiState.passwordVisibility) {
stringResource(
R.string.hide_password

Check warning on line 155 in modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt

View check run for this annotation

Codecov / codecov/patch

modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt#L154-L155

Added lines #L154 - L155 were not covered by tests
)
} else {
stringResource(R.string.show_password)

Check warning on line 158 in modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt

View check run for this annotation

Codecov / codecov/patch

modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt#L157-L158

Added lines #L157 - L158 were not covered by tests
}
)
}
}
)
})
val forgotPasswordAction = Action.Async.ForgotPassword
AsyncTextButton(
text = "Forgot Password?",
text = stringResource(R.string.forgot_password),

Check warning on line 167 in modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt

View check run for this annotation

Codecov / codecov/patch

modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt#L167

Added line #L167 was not covered by tests
isLoading = uiState.pendingActions.contains(forgotPasswordAction),
containerColor = Colors.transparent,
contentPadding = PaddingValues(0.dp),
Expand All @@ -169,11 +175,11 @@
modifier = Modifier.align(Alignment.End)
)
Spacer(modifier = Modifier.height(Spacings.medium))
val passwordSignInOrSignUp = Action.Async.PasswordSignInOrSignUp
val passwordSignIn = Action.Async.PasswordSignIn

Check warning on line 178 in modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt

View check run for this annotation

Codecov / codecov/patch

modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt#L178

Added line #L178 was not covered by tests
AsyncTextButton(
isLoading = uiState.pendingActions.contains(passwordSignInOrSignUp),
text = if (uiState.isAlreadyRegistered) "Login" else "Register",
onClick = { onAction(passwordSignInOrSignUp) },
isLoading = uiState.pendingActions.contains(passwordSignIn),
text = "Login",
onClick = { onAction(passwordSignIn) },

Check warning on line 182 in modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt

View check run for this annotation

Codecov / codecov/patch

modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt#L180-L182

Added lines #L180 - L182 were not covered by tests
modifier = Modifier.fillMaxWidth(),
enabled = uiState.isPasswordSignInEnabled
)
Expand All @@ -183,9 +189,8 @@
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Text("Don't have an Account yet?")
Text(stringResource(R.string.don_t_have_an_account_yet))
TextButton(
enabled = !uiState.isAlreadyRegistered,
onClick = {
onAction(Action.NavigateToRegister)
},
Expand All @@ -194,13 +199,12 @@
}
}
Spacer(modifier = Modifier.height(Spacings.medium))
TextDivider(text = "or")
Spacer(modifier = Modifier.height(Spacings.medium))
TextDivider(stringResource(R.string.or))
VerticalSpacer()

Check warning on line 203 in modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt

View check run for this annotation

Codecov / codecov/patch

modules/account/src/main/kotlin/edu/stanford/spezi/module/account/login/LoginScreen.kt#L202-L203

Added lines #L202 - L203 were not covered by tests
val googleSignInOrSignUp = Action.Async.GoogleSignInOrSignUp
SignInWithGoogleButton(
isLoading = uiState.pendingActions.contains(googleSignInOrSignUp),
onButtonClick = { onAction(googleSignInOrSignUp) },
isAlreadyRegistered = uiState.isAlreadyRegistered,
)
}
}
Expand All @@ -225,7 +229,6 @@
email = FieldState("[email protected]"),
password = FieldState("password"),
passwordVisibility = true,
isAlreadyRegistered = true
)
)
}
Expand Down
Loading
Loading