fix(profiles): connection-profile switch re-dials the WebSocket (#888)

Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
M57andM57 authored and GitHub committed 2026-08-12 23:27:08 +03:00
1 parent 546bd17b18
commit 683a24becf
10 files changed
+183 -17

No files matched your search

@@ -106,6 +106,7 @@ class ChatUpdateCommandTest {
// collectors park harmlessly.
mockkObject(ProfileSwitchCoordinator)
every { ProfileSwitchCoordinator.switched } returns MutableSharedFlow<String>()
every { ProfileSwitchCoordinator.connectionSwitched } returns MutableSharedFlow<String>()
every { HermesWsClient.send(any(), any(), any()) } answers {
reqCount++
@@ -126,6 +126,7 @@ class ChatViewModelTest {
every { AuthManager.getSelectedProfileId() } returns null
mockkObject(ProfileSwitchCoordinator)
every { ProfileSwitchCoordinator.switched } returns mockSwitchFlow
every { ProfileSwitchCoordinator.connectionSwitched } returns MutableSharedFlow<String>()
every { AuthManager.isTypingEffectEnabled() } returns true
every { AuthManager.getTypingEffectDelayMs() } returns 30
every { AuthManager.isAutoReconnect() } returns false
@@ -84,6 +84,7 @@ class SlashCommandDispatchRpcTest {
// pattern) so the collectors park harmlessly.
mockkObject(ProfileSwitchCoordinator)
every { ProfileSwitchCoordinator.switched } returns MutableSharedFlow<String>()
every { ProfileSwitchCoordinator.connectionSwitched } returns MutableSharedFlow<String>()
app = mockk(relaxed = true)
fakeRepo = FakeChatPersistenceRepository()
@@ -3,8 +3,11 @@ package com.m57.hermescontrol.ui.settings
import com.m57.hermescontrol.data.config.ConnectionProfile
import com.m57.hermescontrol.data.local.AuthManager
import com.m57.hermescontrol.data.remote.ApiClient
import com.m57.hermescontrol.data.session.ProfileSwitchCoordinator
import com.m57.hermescontrol.theme.ThemePreference
import com.m57.hermescontrol.theme.ThemePreset
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.mockkObject
import io.mockk.unmockkAll
@@ -84,7 +87,15 @@ class SettingsViewModelTest {
every { AuthManager.getProfileToken(any()) } returns null
every { AuthManager.ensureDefaultProfile() } returns Unit
// Ensure ApiClient.rebuild() is stubbed (used by selectProfile)
// selectProfile/deleteProfile route the switch through the coordinator
// (selection + Retrofit + WebSocket re-dial). Mirror the selection
// side-effect like the real coordinator's setSelectedProfileId does,
// so loadSettings() observes the new selection.
mockkObject(ProfileSwitchCoordinator)
coEvery { ProfileSwitchCoordinator.switchConnectionProfile(any()) } answers {
storedSelectedProfileId = firstArg()
Unit
}
every { ApiClient.rebuild() } returns Unit
}
@@ -158,8 +169,7 @@ class SettingsViewModelTest {
viewModel.selectProfile("prof-2")
testDispatcher.scheduler.advanceUntilIdle()
verify { AuthManager.setSelectedProfileId("prof-2") }
verify { ApiClient.rebuild() }
coVerify { ProfileSwitchCoordinator.switchConnectionProfile("prof-2") }
assertEquals("prof-2", viewModel.uiState.value.selectedProfileId)
assertEquals("Home", viewModel.uiState.value.renameProfileName)
}
@@ -174,8 +184,7 @@ class SettingsViewModelTest {
viewModel.selectProfile(AuthManager.DEFAULT_PROFILE_ID)
testDispatcher.scheduler.advanceUntilIdle()
verify { AuthManager.setSelectedProfileId(AuthManager.DEFAULT_PROFILE_ID) }
verify { ApiClient.rebuild() }
coVerify { ProfileSwitchCoordinator.switchConnectionProfile(AuthManager.DEFAULT_PROFILE_ID) }
assertEquals(AuthManager.DEFAULT_PROFILE_ID, viewModel.uiState.value.selectedProfileId)
}
@@ -187,11 +196,13 @@ class SettingsViewModelTest {
val viewModel = createViewModel()
viewModel.deleteProfile("prof-1")
testDispatcher.scheduler.advanceUntilIdle()
verify { AuthManager.saveConnectionProfiles(any()) }
verify { AuthManager.setProfileToken("prof-1", null) }
verify { AuthManager.setSelectedProfileId(AuthManager.DEFAULT_PROFILE_ID) }
verify { ApiClient.rebuild() }
// The deleted profile was selected — the fallback switch re-homes
// everything (selection + Retrofit + WebSocket) to default.
coVerify { ProfileSwitchCoordinator.switchConnectionProfile(AuthManager.DEFAULT_PROFILE_ID) }
}
@Test
@@ -202,11 +213,13 @@ class SettingsViewModelTest {
val viewModel = createViewModel()
viewModel.deleteProfile("prof-2")
testDispatcher.scheduler.advanceUntilIdle()
verify { AuthManager.saveConnectionProfiles(any()) }
verify { AuthManager.setProfileToken("prof-2", null) }
// Selected profile (prof-1) was NOT deleted — should NOT change selection
verify(exactly = 0) { AuthManager.setSelectedProfileId(any()) }
coVerify(exactly = 0) { ProfileSwitchCoordinator.switchConnectionProfile(any()) }
verify { ApiClient.rebuild() }
}