diff --git a/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt
index afc6be8fa..edea34bde 100644
--- a/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt
+++ b/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt
@@ -266,7 +266,8 @@ class AuthRepositoryImpl constructor(
         val previousActiveUserId = currentUserState.activeUserId
 
         if (userId == previousActiveUserId) {
-            // Nothing to do
+            // No switching to do but clear any special circumstances
+            specialCircumstance = null
             return SwitchAccountResult.NoChange
         }
 
@@ -281,6 +282,10 @@ class AuthRepositoryImpl constructor(
         // Lock and clear data for the previous user
         vaultRepository.lockVaultIfNecessary(previousActiveUserId)
         vaultRepository.clearUnlockedData()
+
+        // Clear any special circumstances
+        specialCircumstance = null
+
         return SwitchAccountResult.AccountSwitched
     }
 
diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreen.kt b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreen.kt
index 1172e65fd..a391995ba 100644
--- a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreen.kt
+++ b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreen.kt
@@ -27,6 +27,7 @@ import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.ExperimentalComposeUiApi
@@ -46,14 +47,18 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.x8bit.bitwarden.R
 import com.x8bit.bitwarden.data.platform.repository.model.Environment
 import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
+import com.x8bit.bitwarden.ui.platform.components.BitwardenAccountSwitcher
 import com.x8bit.bitwarden.ui.platform.components.BitwardenBasicDialog
 import com.x8bit.bitwarden.ui.platform.components.BitwardenFilledButton
+import com.x8bit.bitwarden.ui.platform.components.BitwardenPlaceholderAccountActionItem
 import com.x8bit.bitwarden.ui.platform.components.BitwardenScaffold
 import com.x8bit.bitwarden.ui.platform.components.BitwardenSelectionDialog
 import com.x8bit.bitwarden.ui.platform.components.BitwardenSelectionRow
 import com.x8bit.bitwarden.ui.platform.components.BitwardenSwitch
 import com.x8bit.bitwarden.ui.platform.components.BitwardenTextButton
 import com.x8bit.bitwarden.ui.platform.components.BitwardenTextField
+import com.x8bit.bitwarden.ui.platform.components.BitwardenTopAppBar
+import kotlinx.collections.immutable.toImmutableList
 
 /**
  * The top level composable for the Landing screen.
@@ -86,17 +91,34 @@ fun LandingScreen(
         },
     )
 
-    val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
+    val isAppBarVisible = state.accountSummaries.isNotEmpty()
+    var isAccountMenuVisible by rememberSaveable { mutableStateOf(false) }
+    val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(
+        state = rememberTopAppBarState(),
+        canScroll = { !isAccountMenuVisible },
+    )
     BitwardenScaffold(
         modifier = Modifier
             .fillMaxSize()
             .nestedScroll(scrollBehavior.nestedScrollConnection),
         topBar = {
-            // Empty
+            if (isAppBarVisible) {
+                BitwardenTopAppBar(
+                    title = "",
+                    scrollBehavior = scrollBehavior,
+                    navigationIcon = null,
+                    actions = {
+                        BitwardenPlaceholderAccountActionItem(
+                            onClick = { isAccountMenuVisible = !isAccountMenuVisible },
+                        )
+                    },
+                )
+            }
         },
     ) { innerPadding ->
         LandingScreenContent(
             state = state,
+            isAppBarVisible = isAppBarVisible,
             onEmailInputChange = remember(viewModel) {
                 { viewModel.trySendAction(LandingAction.EmailInputChanged(it)) }
             },
@@ -116,6 +138,23 @@ fun LandingScreen(
                 .padding(innerPadding)
                 .fillMaxSize(),
         )
+
+        BitwardenAccountSwitcher(
+            isVisible = isAccountMenuVisible,
+            accountSummaries = state.accountSummaries.toImmutableList(),
+            onAccountSummaryClick = remember(viewModel) {
+                { viewModel.trySendAction(LandingAction.SwitchAccountClick(it)) }
+            },
+            onAddAccountClick = {
+                // Not available
+            },
+            onDismissRequest = { isAccountMenuVisible = false },
+            isAddAccountAvailable = false,
+            topAppBarScrollBehavior = scrollBehavior,
+            modifier = Modifier
+                .padding(innerPadding)
+                .fillMaxSize(),
+        )
     }
 }
 
@@ -124,6 +163,7 @@ fun LandingScreen(
 @Composable
 private fun LandingScreenContent(
     state: LandingState,
+    isAppBarVisible: Boolean,
     onEmailInputChange: (String) -> Unit,
     onEnvironmentTypeSelect: (Environment.Type) -> Unit,
     onRememberMeToggle: (Boolean) -> Unit,
@@ -138,7 +178,8 @@ private fun LandingScreenContent(
             .imePadding()
             .verticalScroll(rememberScrollState()),
     ) {
-        Spacer(modifier = Modifier.height(104.dp))
+        val topPadding = if (isAppBarVisible) 40.dp else 104.dp
+        Spacer(modifier = Modifier.height(topPadding))
 
         Image(
             painter = painterResource(id = R.drawable.logo),
diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModel.kt
index ef75ec2d2..3af977050 100644
--- a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModel.kt
+++ b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModel.kt
@@ -11,6 +11,8 @@ import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
 import com.x8bit.bitwarden.ui.platform.base.util.asText
 import com.x8bit.bitwarden.ui.platform.base.util.isValidEmail
 import com.x8bit.bitwarden.ui.platform.components.BasicDialogState
+import com.x8bit.bitwarden.ui.platform.components.model.AccountSummary
+import com.x8bit.bitwarden.ui.vault.feature.vault.util.toAccountSummaries
 import dagger.hilt.android.lifecycle.HiltViewModel
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
@@ -36,6 +38,7 @@ class LandingViewModel @Inject constructor(
             isRememberMeEnabled = authRepository.rememberedEmailAddress != null,
             selectedEnvironmentType = environmentRepository.environment.type,
             errorDialogState = BasicDialogState.Hidden,
+            accountSummaries = authRepository.userStateFlow.value?.toAccountSummaries().orEmpty(),
         ),
 ) {
 
@@ -61,6 +64,7 @@ class LandingViewModel @Inject constructor(
 
     override fun handleAction(action: LandingAction) {
         when (action) {
+            is LandingAction.SwitchAccountClick -> handleSwitchAccountClicked(action)
             is LandingAction.ContinueButtonClick -> handleContinueButtonClicked()
             LandingAction.CreateAccountClick -> handleCreateAccountClicked()
             is LandingAction.ErrorDialogDismiss -> handleErrorDialogDismiss()
@@ -73,6 +77,10 @@ class LandingViewModel @Inject constructor(
         }
     }
 
+    private fun handleSwitchAccountClicked(action: LandingAction.SwitchAccountClick) {
+        authRepository.switchAccount(userId = action.account.userId)
+    }
+
     private fun handleEmailInputUpdated(action: LandingAction.EmailInputChanged) {
         val email = action.input
         mutableStateFlow.update {
@@ -156,6 +164,7 @@ data class LandingState(
     val isRememberMeEnabled: Boolean,
     val selectedEnvironmentType: Environment.Type,
     val errorDialogState: BasicDialogState,
+    val accountSummaries: List<AccountSummary>,
 ) : Parcelable
 
 /**
@@ -184,6 +193,13 @@ sealed class LandingEvent {
  * Models actions for the landing screen.
  */
 sealed class LandingAction {
+    /**
+     * Indicates the user has clicked on the given [account] information in order to switch to it.
+     */
+    data class SwitchAccountClick(
+        val account: AccountSummary,
+    ) : LandingAction()
+
     /**
      * Indicates that the continue button has been clicked and the app should navigate to Login.
      */
diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/BitwardenAccountSwitcher.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/BitwardenAccountSwitcher.kt
index 35e95c95b..569765cc7 100644
--- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/BitwardenAccountSwitcher.kt
+++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/BitwardenAccountSwitcher.kt
@@ -66,6 +66,9 @@ private const val MAXIMUM_ACCOUNT_LIMIT = 5
  * @param onAddAccountClick A callback when the Add Account row is clicked.
  * @param onDismissRequest A callback when the component requests to be dismissed. This is triggered
  * whenever the user clicks on the scrim or any of the switcher items.
+ * @param isAddAccountAvailable Whether or not the "Add account" button is available. Note that even
+ * when `true`, this button may be hidden when there are more than [MAXIMUM_ACCOUNT_LIMIT] accounts
+ * present.
  * @param modifier A [Modifier] for the composable.
  * @param topAppBarScrollBehavior Used to derive the background color of the content and keep it in
  * sync with the associated app bar.
@@ -79,6 +82,7 @@ fun BitwardenAccountSwitcher(
     onAddAccountClick: () -> Unit,
     onDismissRequest: () -> Unit,
     modifier: Modifier = Modifier,
+    isAddAccountAvailable: Boolean = true,
     topAppBarScrollBehavior: TopAppBarScrollBehavior,
 ) {
     Box(modifier = modifier) {
@@ -99,6 +103,7 @@ fun BitwardenAccountSwitcher(
                 onDismissRequest()
                 onAddAccountClick()
             },
+            isAddAccountAvailable = isAddAccountAvailable,
             topAppBarScrollBehavior = topAppBarScrollBehavior,
             modifier = Modifier
                 .fillMaxWidth(),
@@ -113,6 +118,7 @@ private fun AnimatedAccountSwitcher(
     accountSummaries: ImmutableList<AccountSummary>,
     onAccountSummaryClick: (AccountSummary) -> Unit,
     onAddAccountClick: () -> Unit,
+    isAddAccountAvailable: Boolean,
     modifier: Modifier = Modifier,
     topAppBarScrollBehavior: TopAppBarScrollBehavior,
 ) {
@@ -130,11 +136,16 @@ private fun AnimatedAccountSwitcher(
                 .padding(bottom = 24.dp)
                 // Match the color of the switcher the different states of the app bar.
                 .drawBehind {
+                    val progressFraction = if (topAppBarScrollBehavior.isPinned) {
+                        topAppBarScrollBehavior.state.overlappedFraction
+                    } else {
+                        topAppBarScrollBehavior.state.collapsedFraction
+                    }
                     val contentBackgroundColor =
                         lerp(
                             start = expandedColor,
                             stop = collapsedColor,
-                            fraction = topAppBarScrollBehavior.state.collapsedFraction,
+                            fraction = progressFraction,
                         )
                     drawRect(contentBackgroundColor)
                 },
@@ -154,7 +165,7 @@ private fun AnimatedAccountSwitcher(
                     color = MaterialTheme.colorScheme.outlineVariant,
                 )
             }
-            if (accountSummaries.size < MAXIMUM_ACCOUNT_LIMIT) {
+            if (accountSummaries.size < MAXIMUM_ACCOUNT_LIMIT && isAddAccountAvailable) {
                 item {
                     AddAccountItem(
                         onClick = onAddAccountClick,
diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/BitwardenPlaceholderAccountItem.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/BitwardenPlaceholderAccountItem.kt
new file mode 100644
index 000000000..c512359cc
--- /dev/null
+++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/BitwardenPlaceholderAccountItem.kt
@@ -0,0 +1,60 @@
+package com.x8bit.bitwarden.ui.platform.components
+
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.tooling.preview.Preview
+import com.x8bit.bitwarden.R
+import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
+
+/**
+ * A placeholder item to be used to represent an account.
+ *
+ * @param onClick An action to be invoked when the icon is clicked.
+ */
+@Composable
+fun BitwardenPlaceholderAccountActionItem(
+    onClick: () -> Unit,
+) {
+    IconButton(
+        onClick = onClick,
+        modifier = Modifier
+            .semantics(mergeDescendants = true) {},
+    ) {
+        Icon(
+            painter = painterResource(id = R.drawable.ic_account_initials_container),
+            contentDescription = null,
+            tint = MaterialTheme.colorScheme.secondaryContainer,
+        )
+        Icon(
+            painter = painterResource(id = R.drawable.ic_dots),
+            contentDescription = stringResource(id = R.string.account),
+            tint = MaterialTheme.colorScheme.onSecondaryContainer,
+        )
+    }
+}
+
+@Preview
+@Composable
+private fun BitwardenPlaceholderAccountActionItem_preview_light() {
+    BitwardenTheme(darkTheme = false) {
+        BitwardenPlaceholderAccountActionItem(
+            onClick = {},
+        )
+    }
+}
+
+@Preview
+@Composable
+private fun BitwardenPlaceholderAccountActionItem_preview_dark() {
+    BitwardenTheme(darkTheme = true) {
+        BitwardenPlaceholderAccountActionItem(
+            onClick = {},
+        )
+    }
+}
diff --git a/app/src/main/res/drawable/ic_dots.xml b/app/src/main/res/drawable/ic_dots.xml
new file mode 100644
index 000000000..1108735d0
--- /dev/null
+++ b/app/src/main/res/drawable/ic_dots.xml
@@ -0,0 +1,12 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:pathData="M13.663,12.05C13.663,11.756 13.753,11.509 13.934,11.309C14.122,11.103 14.391,11 14.741,11C15.091,11 15.356,11.103 15.538,11.309C15.725,11.509 15.819,11.756 15.819,12.05C15.819,12.337 15.725,12.581 15.538,12.781C15.356,12.981 15.091,13.081 14.741,13.081C14.391,13.081 14.122,12.981 13.934,12.781C13.753,12.581 13.663,12.337 13.663,12.05Z"
+      android:fillColor="#151B2C"/>
+  <path
+      android:pathData="M8,12.05C8,11.756 8.091,11.509 8.272,11.309C8.459,11.103 8.728,11 9.078,11C9.428,11 9.694,11.103 9.875,11.309C10.063,11.509 10.156,11.756 10.156,12.05C10.156,12.337 10.063,12.581 9.875,12.781C9.694,12.981 9.428,13.081 9.078,13.081C8.728,13.081 8.459,12.981 8.272,12.781C8.091,12.581 8,12.337 8,12.05Z"
+      android:fillColor="#151B2C"/>
+</vector>
diff --git a/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt
index eb12605bc..4a2df773a 100644
--- a/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt
+++ b/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt
@@ -1099,7 +1099,7 @@ class AuthRepositoryTest {
 
     @Suppress("MaxLineLength")
     @Test
-    fun `switchAccount when the given userId is the same as the current activeUserId should do nothing`() {
+    fun `switchAccount when the given userId is the same as the current activeUserId should only clear any special circumstances`() {
         val originalUserId = USER_ID_1
         val originalUserState = SINGLE_USER_STATE_1.toUserState(
             vaultState = VAULT_STATE,
@@ -1110,6 +1110,7 @@ class AuthRepositoryTest {
             originalUserState,
             repository.userStateFlow.value,
         )
+        repository.specialCircumstance = UserState.SpecialCircumstance.PendingAccountAddition
 
         assertEquals(
             SwitchAccountResult.NoChange,
@@ -1120,6 +1121,7 @@ class AuthRepositoryTest {
             originalUserState,
             repository.userStateFlow.value,
         )
+        assertNull(repository.specialCircumstance)
         verify(exactly = 0) { vaultRepository.lockVaultIfNecessary(originalUserId) }
         verify(exactly = 0) { vaultRepository.clearUnlockedData() }
     }
@@ -1154,7 +1156,7 @@ class AuthRepositoryTest {
 
     @Suppress("MaxLineLength")
     @Test
-    fun `switchAccount when the userId is valid should update the current UserState, lock the vault of the previous active user, and clear the previously unlocked data`() {
+    fun `switchAccount when the userId is valid should update the current UserState, lock the vault of the previous active user, clear the previously unlocked data, and reset the special circumstance`() {
         val originalUserId = USER_ID_1
         val updatedUserId = USER_ID_2
         val originalUserState = MULTI_USER_STATE.toUserState(
@@ -1166,6 +1168,7 @@ class AuthRepositoryTest {
             originalUserState,
             repository.userStateFlow.value,
         )
+        repository.specialCircumstance = UserState.SpecialCircumstance.PendingAccountAddition
 
         assertEquals(
             SwitchAccountResult.AccountSwitched,
@@ -1176,6 +1179,7 @@ class AuthRepositoryTest {
             originalUserState.copy(activeUserId = updatedUserId),
             repository.userStateFlow.value,
         )
+        assertNull(repository.specialCircumstance)
         verify { vaultRepository.lockVaultIfNecessary(originalUserId) }
         verify { vaultRepository.clearUnlockedData() }
     }
diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreenTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreenTest.kt
index 4778b624a..036bfd7e5 100644
--- a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreenTest.kt
+++ b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreenTest.kt
@@ -12,6 +12,7 @@ import androidx.compose.ui.test.filterToOne
 import androidx.compose.ui.test.hasAnyAncestor
 import androidx.compose.ui.test.isDialog
 import androidx.compose.ui.test.onAllNodesWithText
+import androidx.compose.ui.test.onNodeWithContentDescription
 import androidx.compose.ui.test.onNodeWithText
 import androidx.compose.ui.test.performClick
 import androidx.compose.ui.test.performScrollTo
@@ -21,6 +22,7 @@ import com.x8bit.bitwarden.data.platform.repository.model.Environment
 import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest
 import com.x8bit.bitwarden.ui.platform.base.util.asText
 import com.x8bit.bitwarden.ui.platform.components.BasicDialogState
+import com.x8bit.bitwarden.ui.platform.components.model.AccountSummary
 import io.mockk.every
 import io.mockk.mockk
 import io.mockk.verify
@@ -63,6 +65,58 @@ class LandingScreenTest : BaseComposeTest() {
         }
     }
 
+    @Test
+    fun `account menu icon is present according to the state`() {
+        composeTestRule.onNodeWithContentDescription("Account").assertDoesNotExist()
+
+        mutableStateFlow.update {
+            it.copy(accountSummaries = listOf(ACTIVE_ACCOUNT_SUMMARY))
+        }
+
+        composeTestRule.onNodeWithContentDescription("Account").assertIsDisplayed()
+    }
+
+    @Test
+    fun `account menu icon click should show the account switcher`() {
+        mutableStateFlow.update {
+            it.copy(accountSummaries = listOf(ACTIVE_ACCOUNT_SUMMARY))
+        }
+
+        composeTestRule.onNodeWithContentDescription("Account").performClick()
+
+        composeTestRule.onNodeWithText("active@bitwarden.com").assertIsDisplayed()
+    }
+
+    @Suppress("MaxLineLength")
+    @Test
+    fun `account click in the account switcher should send SwitchAccountClick and close switcher`() {
+        // Show the account switcher
+        mutableStateFlow.update {
+            it.copy(accountSummaries = listOf(ACTIVE_ACCOUNT_SUMMARY))
+        }
+        composeTestRule.onNodeWithContentDescription("Account").performClick()
+        composeTestRule.onNodeWithText("active@bitwarden.com").assertIsDisplayed()
+
+        composeTestRule.onNodeWithText("active@bitwarden.com").performClick()
+
+        verify {
+            viewModel.trySendAction(LandingAction.SwitchAccountClick(ACTIVE_ACCOUNT_SUMMARY))
+        }
+        composeTestRule.onNodeWithText("active@bitwarden.com").assertDoesNotExist()
+    }
+
+    @Test
+    fun `add account button in the account switcher does not exist`() {
+        // Show the account switcher
+        mutableStateFlow.update {
+            it.copy(accountSummaries = listOf(ACTIVE_ACCOUNT_SUMMARY))
+        }
+        composeTestRule.onNodeWithContentDescription("Account").performClick()
+        composeTestRule.onNodeWithText("active@bitwarden.com").assertIsDisplayed()
+
+        composeTestRule.onNodeWithText("Add account").assertDoesNotExist()
+    }
+
     @Test
     fun `continue button should be enabled or disabled according to the state`() {
         composeTestRule.onNodeWithText("Continue").assertIsEnabled()
@@ -224,10 +278,19 @@ class LandingScreenTest : BaseComposeTest() {
     }
 }
 
+private val ACTIVE_ACCOUNT_SUMMARY = AccountSummary(
+    userId = "activeUserId",
+    name = "Active User",
+    email = "active@bitwarden.com",
+    avatarColorHex = "#aa00aa",
+    status = AccountSummary.Status.ACTIVE,
+)
+
 private val DEFAULT_STATE = LandingState(
     emailInput = "",
     isContinueButtonEnabled = true,
     isRememberMeEnabled = false,
     selectedEnvironmentType = Environment.Type.US,
     errorDialogState = BasicDialogState.Hidden,
+    accountSummaries = emptyList(),
 )
diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModelTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModelTest.kt
index ac344c776..8455ff9bb 100644
--- a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModelTest.kt
+++ b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModelTest.kt
@@ -3,13 +3,16 @@ package com.x8bit.bitwarden.ui.auth.feature.landing
 import androidx.lifecycle.SavedStateHandle
 import app.cash.turbine.test
 import com.x8bit.bitwarden.R
+import com.x8bit.bitwarden.data.auth.repository.model.UserState
 import com.x8bit.bitwarden.data.platform.repository.model.Environment
 import com.x8bit.bitwarden.data.platform.repository.util.FakeEnvironmentRepository
 import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
 import com.x8bit.bitwarden.ui.platform.base.util.asText
 import com.x8bit.bitwarden.ui.platform.components.BasicDialogState
+import com.x8bit.bitwarden.ui.vault.feature.vault.util.toAccountSummaries
 import io.mockk.every
 import io.mockk.mockk
+import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.runTest
 import org.junit.jupiter.api.Assertions.assertEquals
 import org.junit.jupiter.api.Test
@@ -42,6 +45,30 @@ class LandingViewModelTest : BaseViewModelTest() {
         }
     }
 
+    @Test
+    fun `initial state should set the account summaries based on the UserState`() {
+        val userState = UserState(
+            activeUserId = "activeUserId",
+            accounts = listOf(
+                UserState.Account(
+                    userId = "activeUserId",
+                    name = "name",
+                    email = "email",
+                    avatarColorHex = "avatarColorHex",
+                    isPremium = true,
+                    isVaultUnlocked = true,
+                ),
+            ),
+        )
+        val viewModel = createViewModel(userState = userState)
+        assertEquals(
+            DEFAULT_STATE.copy(
+                accountSummaries = userState.toAccountSummaries(),
+            ),
+            viewModel.stateFlow.value,
+        )
+    }
+
     @Test
     fun `initial state should pull from saved state handle when present`() = runTest {
         val expectedState = DEFAULT_STATE.copy(
@@ -180,10 +207,12 @@ class LandingViewModelTest : BaseViewModelTest() {
 
     private fun createViewModel(
         rememberedEmail: String? = null,
+        userState: UserState? = null,
         savedStateHandle: SavedStateHandle = SavedStateHandle(),
     ): LandingViewModel = LandingViewModel(
         authRepository = mockk(relaxed = true) {
             every { rememberedEmailAddress } returns rememberedEmail
+            every { userStateFlow } returns MutableStateFlow(userState)
         },
         environmentRepository = fakeEnvironmentRepository,
         savedStateHandle = savedStateHandle,
@@ -198,6 +227,7 @@ class LandingViewModelTest : BaseViewModelTest() {
             isRememberMeEnabled = false,
             selectedEnvironmentType = Environment.Type.US,
             errorDialogState = BasicDialogState.Hidden,
+            accountSummaries = emptyList(),
         )
     }
 }