mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-10-31 16:22:49 +00:00
Adapt HealthChat to upstream v26.10.0
Follow-ups needed after rebasing the HealthChat series from v26.07.0 onto v26.10.0 that span several of the replayed commits: - Rename the five PreviewParameterProvider subclasses in features/healthchat to the *PreviewParam suffix now enforced by Konsist. - Rename MemberDirectoryEvents and HealthChatProfileSectionEvents to the *Event suffix used by every upstream sealed interface. - Import FakeStartDMAction from features/startchat/test, where it lives now. - ListItem lost its headlineContent parameter in favour of content. - HomeView gained onAddAccountClick and onSwitchToAccount, and onRoomClick now carries an EventId; update HomeViewBackHandlingTest accordingly. - Restore upstream's codecov-action pin (v7.1.1) that the CI squash carried back to v7.0.0. - Gate the new pr-checks.yml on the upstream repository: this fork does not use the PR- label convention. - Add the 26.10.0 section to HEALTHCHAT_CHANGES.md.
This commit is contained in:
@@ -10,6 +10,8 @@ permissions: {}
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pr-checks:
|
pr-checks:
|
||||||
|
# Upstream-only: this fork does not use the PR- label convention.
|
||||||
|
if: github.repository == 'element-hq/element-x-android'
|
||||||
name: PR Checks
|
name: PR Checks
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 5
|
timeout-minutes: 5
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ jobs:
|
|||||||
if: env.CODECOV_TOKEN != ''
|
if: env.CODECOV_TOKEN != ''
|
||||||
env:
|
env:
|
||||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||||
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
|
||||||
with:
|
with:
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|||||||
@@ -6,6 +6,18 @@ top section matching the released version — the heading must have the exact
|
|||||||
form `## Changes in <version> (<date>)` and the whole section must stay under
|
form `## Changes in <version> (<date>)` and the whole section must stay under
|
||||||
500 characters. See `.claude/skills/releasing-healthchat/SKILL.md`.
|
500 characters. See `.claude/skills/releasing-healthchat/SKILL.md`.
|
||||||
|
|
||||||
|
## Changes in 26.10.0 (2026-10-19)
|
||||||
|
|
||||||
|
🎉 Neue Funktionen
|
||||||
|
|
||||||
|
- Nachrichtensuche: Chats durchsuchen, auch in verschlüsselten Räumen.
|
||||||
|
- Umfragen mit Mehrfachauswahl.
|
||||||
|
|
||||||
|
🙌 Verbesserungen
|
||||||
|
|
||||||
|
- Basis aktualisiert auf Element X 26.10.0 mit zahlreichen Fehlerbehebungen.
|
||||||
|
- Einstellungen neu gegliedert in Konto- und App-Einstellungen.
|
||||||
|
|
||||||
## Changes in 26.08.0 (2026-08-06)
|
## Changes in 26.08.0 (2026-08-06)
|
||||||
|
|
||||||
🎉 Neue Funktionen
|
🎉 Neue Funktionen
|
||||||
|
|||||||
+5
-5
@@ -10,17 +10,17 @@ package io.element.android.features.healthchat.api.directory
|
|||||||
|
|
||||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||||
|
|
||||||
sealed interface MemberDirectoryEvents {
|
sealed interface MemberDirectoryEvent {
|
||||||
/**
|
/**
|
||||||
* Fired by the view on first composition. The tab presenter runs from app start (it is
|
* Fired by the view on first composition. The tab presenter runs from app start (it is
|
||||||
* composed by the Home presenter), so the first fetch is deferred until the tab is shown.
|
* composed by the Home presenter), so the first fetch is deferred until the tab is shown.
|
||||||
*/
|
*/
|
||||||
data object LoadIfNeeded : MemberDirectoryEvents
|
data object LoadIfNeeded : MemberDirectoryEvent
|
||||||
|
|
||||||
/** Header refresh and "try again" — one load path. */
|
/** Header refresh and "try again" — one load path. */
|
||||||
data object Refresh : MemberDirectoryEvents
|
data object Refresh : MemberDirectoryEvent
|
||||||
|
|
||||||
data class StartDm(val matrixUser: MatrixUser) : MemberDirectoryEvents
|
data class StartDm(val matrixUser: MatrixUser) : MemberDirectoryEvent
|
||||||
|
|
||||||
data object ClearStartDmState : MemberDirectoryEvents
|
data object ClearStartDmState : MemberDirectoryEvent
|
||||||
}
|
}
|
||||||
+1
-1
@@ -18,7 +18,7 @@ data class MemberDirectoryState(
|
|||||||
val searchQuery: TextFieldState,
|
val searchQuery: TextFieldState,
|
||||||
val directory: AsyncData<HealthChatMemberDirectory>,
|
val directory: AsyncData<HealthChatMemberDirectory>,
|
||||||
val startDmActionState: AsyncAction<RoomId>,
|
val startDmActionState: AsyncAction<RoomId>,
|
||||||
val eventSink: (MemberDirectoryEvents) -> Unit,
|
val eventSink: (MemberDirectoryEvent) -> Unit,
|
||||||
) {
|
) {
|
||||||
/** Unknown-while-loading counts as approved so no banner flashes during the first load. */
|
/** Unknown-while-loading counts as approved so no banner flashes during the first load. */
|
||||||
val isApproved: Boolean
|
val isApproved: Boolean
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ fun aMemberDirectoryState(
|
|||||||
searchQuery: TextFieldState = TextFieldState(),
|
searchQuery: TextFieldState = TextFieldState(),
|
||||||
directory: AsyncData<HealthChatMemberDirectory> = AsyncData.Success(aMemberDirectory()),
|
directory: AsyncData<HealthChatMemberDirectory> = AsyncData.Success(aMemberDirectory()),
|
||||||
startDmActionState: AsyncAction<RoomId> = AsyncAction.Uninitialized,
|
startDmActionState: AsyncAction<RoomId> = AsyncAction.Uninitialized,
|
||||||
eventSink: (MemberDirectoryEvents) -> Unit = {},
|
eventSink: (MemberDirectoryEvent) -> Unit = {},
|
||||||
) = MemberDirectoryState(
|
) = MemberDirectoryState(
|
||||||
searchQuery = searchQuery,
|
searchQuery = searchQuery,
|
||||||
directory = directory,
|
directory = directory,
|
||||||
|
|||||||
+6
-6
@@ -21,7 +21,7 @@ import androidx.compose.runtime.setValue
|
|||||||
import dev.zacsweers.metro.Inject
|
import dev.zacsweers.metro.Inject
|
||||||
import io.element.android.features.healthchat.api.HealthChatDirectoryService
|
import io.element.android.features.healthchat.api.HealthChatDirectoryService
|
||||||
import io.element.android.features.healthchat.api.HealthChatMemberDirectory
|
import io.element.android.features.healthchat.api.HealthChatMemberDirectory
|
||||||
import io.element.android.features.healthchat.api.directory.MemberDirectoryEvents
|
import io.element.android.features.healthchat.api.directory.MemberDirectoryEvent
|
||||||
import io.element.android.features.healthchat.api.directory.MemberDirectoryState
|
import io.element.android.features.healthchat.api.directory.MemberDirectoryState
|
||||||
import io.element.android.features.startchat.api.StartDMAction
|
import io.element.android.features.startchat.api.StartDMAction
|
||||||
import io.element.android.libraries.architecture.AsyncAction
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
@@ -62,22 +62,22 @@ class MemberDirectoryPresenter(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun handleEvents(event: MemberDirectoryEvents) {
|
fun handleEvents(event: MemberDirectoryEvent) {
|
||||||
when (event) {
|
when (event) {
|
||||||
MemberDirectoryEvents.LoadIfNeeded -> {
|
MemberDirectoryEvent.LoadIfNeeded -> {
|
||||||
hasBeenRequested = true
|
hasBeenRequested = true
|
||||||
}
|
}
|
||||||
MemberDirectoryEvents.Refresh -> {
|
MemberDirectoryEvent.Refresh -> {
|
||||||
loadTrigger++
|
loadTrigger++
|
||||||
}
|
}
|
||||||
is MemberDirectoryEvents.StartDm -> coroutineScope.launch {
|
is MemberDirectoryEvent.StartDm -> coroutineScope.launch {
|
||||||
startDMAction.execute(
|
startDMAction.execute(
|
||||||
matrixUser = event.matrixUser,
|
matrixUser = event.matrixUser,
|
||||||
createIfDmDoesNotExist = startDmActionState.value is AsyncAction.Confirming,
|
createIfDmDoesNotExist = startDmActionState.value is AsyncAction.Confirming,
|
||||||
actionState = startDmActionState,
|
actionState = startDmActionState,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
MemberDirectoryEvents.ClearStartDmState -> {
|
MemberDirectoryEvent.ClearStartDmState -> {
|
||||||
startDmActionState.value = AsyncAction.Uninitialized
|
startDmActionState.value = AsyncAction.Uninitialized
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@ import io.element.android.features.healthchat.api.directory.aMemberDirectory
|
|||||||
import io.element.android.features.healthchat.api.directory.aMemberDirectoryState
|
import io.element.android.features.healthchat.api.directory.aMemberDirectoryState
|
||||||
import io.element.android.libraries.architecture.AsyncData
|
import io.element.android.libraries.architecture.AsyncData
|
||||||
|
|
||||||
open class MemberDirectoryStateProvider : PreviewParameterProvider<MemberDirectoryState> {
|
open class MemberDirectoryStatePreviewParam : PreviewParameterProvider<MemberDirectoryState> {
|
||||||
override val values: Sequence<MemberDirectoryState>
|
override val values: Sequence<MemberDirectoryState>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
aMemberDirectoryState(),
|
aMemberDirectoryState(),
|
||||||
+9
-9
@@ -27,7 +27,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import io.element.android.compound.theme.ElementTheme
|
import io.element.android.compound.theme.ElementTheme
|
||||||
import io.element.android.features.healthchat.api.HealthChatStrings
|
import io.element.android.features.healthchat.api.HealthChatStrings
|
||||||
import io.element.android.features.healthchat.api.directory.MemberDirectoryEvents
|
import io.element.android.features.healthchat.api.directory.MemberDirectoryEvent
|
||||||
import io.element.android.features.healthchat.api.directory.MemberDirectoryState
|
import io.element.android.features.healthchat.api.directory.MemberDirectoryState
|
||||||
import io.element.android.features.healthchat.api.toMatrixUser
|
import io.element.android.features.healthchat.api.toMatrixUser
|
||||||
import io.element.android.features.healthchat.impl.directory.components.MemberCard
|
import io.element.android.features.healthchat.impl.directory.components.MemberCard
|
||||||
@@ -63,7 +63,7 @@ fun MemberDirectoryView(
|
|||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
state.eventSink(MemberDirectoryEvents.LoadIfNeeded)
|
state.eventSink(MemberDirectoryEvent.LoadIfNeeded)
|
||||||
}
|
}
|
||||||
Box(modifier = modifier.fillMaxSize()) {
|
Box(modifier = modifier.fillMaxSize()) {
|
||||||
when (val directory = state.directory) {
|
when (val directory = state.directory) {
|
||||||
@@ -84,7 +84,7 @@ fun MemberDirectoryView(
|
|||||||
}
|
}
|
||||||
is AsyncData.Failure -> MemberDirectoryErrorContent(
|
is AsyncData.Failure -> MemberDirectoryErrorContent(
|
||||||
message = directory.error.healthChatUserMessage(),
|
message = directory.error.healthChatUserMessage(),
|
||||||
onRetry = { state.eventSink(MemberDirectoryEvents.Refresh) },
|
onRetry = { state.eventSink(MemberDirectoryEvent.Refresh) },
|
||||||
)
|
)
|
||||||
is AsyncData.Success -> MemberDirectoryContent(
|
is AsyncData.Success -> MemberDirectoryContent(
|
||||||
state = state,
|
state = state,
|
||||||
@@ -107,17 +107,17 @@ fun MemberDirectoryView(
|
|||||||
onSuccess = onOpenDm,
|
onSuccess = onOpenDm,
|
||||||
errorMessage = { stringResource(HealthChatStrings.healthchat_screen_member_directory_error_starting_chat) },
|
errorMessage = { stringResource(HealthChatStrings.healthchat_screen_member_directory_error_starting_chat) },
|
||||||
onRetry = null,
|
onRetry = null,
|
||||||
onErrorDismiss = { state.eventSink(MemberDirectoryEvents.ClearStartDmState) },
|
onErrorDismiss = { state.eventSink(MemberDirectoryEvent.ClearStartDmState) },
|
||||||
confirmationDialog = { data ->
|
confirmationDialog = { data ->
|
||||||
if (data is ConfirmingStartDmWithMatrixUser) {
|
if (data is ConfirmingStartDmWithMatrixUser) {
|
||||||
CreateDmConfirmationBottomSheet(
|
CreateDmConfirmationBottomSheet(
|
||||||
matrixUser = data.matrixUser,
|
matrixUser = data.matrixUser,
|
||||||
isUserIdentityUnknown = data.isUserIdentityUnknown,
|
isUserIdentityUnknown = data.isUserIdentityUnknown,
|
||||||
onSendInvite = {
|
onSendInvite = {
|
||||||
state.eventSink(MemberDirectoryEvents.StartDm(data.matrixUser))
|
state.eventSink(MemberDirectoryEvent.StartDm(data.matrixUser))
|
||||||
},
|
},
|
||||||
onDismiss = {
|
onDismiss = {
|
||||||
state.eventSink(MemberDirectoryEvents.ClearStartDmState)
|
state.eventSink(MemberDirectoryEvent.ClearStartDmState)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,7 @@ private fun MemberDirectoryContent(
|
|||||||
onMyProfileClick = onMyProfileClick,
|
onMyProfileClick = onMyProfileClick,
|
||||||
onEditProfileClick = onEditProfileClick,
|
onEditProfileClick = onEditProfileClick,
|
||||||
onInviteClick = if (state.isApproved) onInviteClick else null,
|
onInviteClick = if (state.isApproved) onInviteClick else null,
|
||||||
onRefreshClick = { state.eventSink(MemberDirectoryEvents.Refresh) },
|
onRefreshClick = { state.eventSink(MemberDirectoryEvent.Refresh) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (!state.isApproved) {
|
if (!state.isApproved) {
|
||||||
@@ -196,7 +196,7 @@ private fun MemberDirectoryContent(
|
|||||||
MemberCard(
|
MemberCard(
|
||||||
member = member,
|
member = member,
|
||||||
onClick = onMemberClick?.let { callback -> { callback(member.userId) } },
|
onClick = onMemberClick?.let { callback -> { callback(member.userId) } },
|
||||||
onStartChatClick = { state.eventSink(MemberDirectoryEvents.StartDm(member.toMatrixUser())) },
|
onStartChatClick = { state.eventSink(MemberDirectoryEvent.StartDm(member.toMatrixUser())) },
|
||||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp),
|
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -219,7 +219,7 @@ private fun FullScreenLoading(
|
|||||||
@PreviewsDayNight
|
@PreviewsDayNight
|
||||||
@Composable
|
@Composable
|
||||||
internal fun MemberDirectoryViewPreview(
|
internal fun MemberDirectoryViewPreview(
|
||||||
@PreviewParameter(MemberDirectoryStateProvider::class) state: MemberDirectoryState
|
@PreviewParameter(MemberDirectoryStatePreviewParam::class) state: MemberDirectoryState
|
||||||
) = ElementPreview {
|
) = ElementPreview {
|
||||||
MemberDirectoryView(
|
MemberDirectoryView(
|
||||||
state = state,
|
state = state,
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
|||||||
import io.element.android.features.healthchat.api.HealthChatStrings
|
import io.element.android.features.healthchat.api.HealthChatStrings
|
||||||
import io.element.android.libraries.architecture.AsyncAction
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
|
|
||||||
open class HealthChatInviteStateProvider : PreviewParameterProvider<HealthChatInviteState> {
|
open class HealthChatInviteStatePreviewParam : PreviewParameterProvider<HealthChatInviteState> {
|
||||||
override val values: Sequence<HealthChatInviteState>
|
override val values: Sequence<HealthChatInviteState>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
aHealthChatInviteState(),
|
aHealthChatInviteState(),
|
||||||
+1
-1
@@ -136,7 +136,7 @@ private fun HealthChatFieldError.text(): String {
|
|||||||
@PreviewsDayNight
|
@PreviewsDayNight
|
||||||
@Composable
|
@Composable
|
||||||
internal fun HealthChatInviteViewPreview(
|
internal fun HealthChatInviteViewPreview(
|
||||||
@PreviewParameter(HealthChatInviteStateProvider::class) state: HealthChatInviteState
|
@PreviewParameter(HealthChatInviteStatePreviewParam::class) state: HealthChatInviteState
|
||||||
) = ElementPreview {
|
) = ElementPreview {
|
||||||
HealthChatInviteView(
|
HealthChatInviteView(
|
||||||
state = state,
|
state = state,
|
||||||
|
|||||||
+1
-1
@@ -24,7 +24,7 @@ import kotlinx.collections.immutable.persistentListOf
|
|||||||
import kotlinx.collections.immutable.persistentMapOf
|
import kotlinx.collections.immutable.persistentMapOf
|
||||||
import kotlinx.collections.immutable.toImmutableMap
|
import kotlinx.collections.immutable.toImmutableMap
|
||||||
|
|
||||||
open class EditHealthChatProfileStateProvider : PreviewParameterProvider<EditHealthChatProfileState> {
|
open class EditHealthChatProfileStatePreviewParam : PreviewParameterProvider<EditHealthChatProfileState> {
|
||||||
override val values: Sequence<EditHealthChatProfileState>
|
override val values: Sequence<EditHealthChatProfileState>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
anEditHealthChatProfileState(),
|
anEditHealthChatProfileState(),
|
||||||
+1
-1
@@ -284,7 +284,7 @@ private fun ProfileFormField(
|
|||||||
@PreviewsDayNight
|
@PreviewsDayNight
|
||||||
@Composable
|
@Composable
|
||||||
internal fun EditHealthChatProfileViewPreview(
|
internal fun EditHealthChatProfileViewPreview(
|
||||||
@PreviewParameter(EditHealthChatProfileStateProvider::class) state: EditHealthChatProfileState
|
@PreviewParameter(EditHealthChatProfileStatePreviewParam::class) state: EditHealthChatProfileState
|
||||||
) = ElementPreview {
|
) = ElementPreview {
|
||||||
EditHealthChatProfileView(
|
EditHealthChatProfileView(
|
||||||
state = state,
|
state = state,
|
||||||
|
|||||||
+2
-2
@@ -8,6 +8,6 @@
|
|||||||
|
|
||||||
package io.element.android.features.healthchat.impl.profile.section
|
package io.element.android.features.healthchat.impl.profile.section
|
||||||
|
|
||||||
sealed interface HealthChatProfileSectionEvents {
|
sealed interface HealthChatProfileSectionEvent {
|
||||||
data object Retry : HealthChatProfileSectionEvents
|
data object Retry : HealthChatProfileSectionEvent
|
||||||
}
|
}
|
||||||
+2
-2
@@ -63,9 +63,9 @@ class HealthChatProfileSectionPresenter(
|
|||||||
memberProfile
|
memberProfile
|
||||||
}
|
}
|
||||||
|
|
||||||
fun handleEvents(event: HealthChatProfileSectionEvents) {
|
fun handleEvents(event: HealthChatProfileSectionEvent) {
|
||||||
when (event) {
|
when (event) {
|
||||||
HealthChatProfileSectionEvents.Retry -> retryTrigger++
|
HealthChatProfileSectionEvent.Retry -> retryTrigger++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -13,5 +13,5 @@ import io.element.android.libraries.architecture.AsyncData
|
|||||||
|
|
||||||
data class HealthChatProfileSectionState(
|
data class HealthChatProfileSectionState(
|
||||||
val profile: AsyncData<HealthChatMember>,
|
val profile: AsyncData<HealthChatMember>,
|
||||||
val eventSink: (HealthChatProfileSectionEvents) -> Unit,
|
val eventSink: (HealthChatProfileSectionEvent) -> Unit,
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-2
@@ -14,7 +14,7 @@ import io.element.android.features.healthchat.api.HealthChatMember
|
|||||||
import io.element.android.libraries.architecture.AsyncData
|
import io.element.android.libraries.architecture.AsyncData
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
|
|
||||||
open class HealthChatProfileSectionStateProvider : PreviewParameterProvider<HealthChatProfileSectionState> {
|
open class HealthChatProfileSectionStatePreviewParam : PreviewParameterProvider<HealthChatProfileSectionState> {
|
||||||
override val values: Sequence<HealthChatProfileSectionState>
|
override val values: Sequence<HealthChatProfileSectionState>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
aHealthChatProfileSectionState(profile = AsyncData.Success(aProfileSectionMember())),
|
aHealthChatProfileSectionState(profile = AsyncData.Success(aProfileSectionMember())),
|
||||||
@@ -45,7 +45,7 @@ open class HealthChatProfileSectionStateProvider : PreviewParameterProvider<Heal
|
|||||||
|
|
||||||
fun aHealthChatProfileSectionState(
|
fun aHealthChatProfileSectionState(
|
||||||
profile: AsyncData<HealthChatMember> = AsyncData.Uninitialized,
|
profile: AsyncData<HealthChatMember> = AsyncData.Uninitialized,
|
||||||
eventSink: (HealthChatProfileSectionEvents) -> Unit = {},
|
eventSink: (HealthChatProfileSectionEvent) -> Unit = {},
|
||||||
) = HealthChatProfileSectionState(
|
) = HealthChatProfileSectionState(
|
||||||
profile = profile,
|
profile = profile,
|
||||||
eventSink = eventSink,
|
eventSink = eventSink,
|
||||||
+4
-4
@@ -56,7 +56,7 @@ fun HealthChatProfileSectionView(
|
|||||||
is HealthChatApiException.NotFound -> Unit
|
is HealthChatApiException.NotFound -> Unit
|
||||||
is HealthChatApiException.NotApproved -> NotApprovedHint(modifier = modifier)
|
is HealthChatApiException.NotApproved -> NotApprovedHint(modifier = modifier)
|
||||||
else -> LoadingErrorRow(
|
else -> LoadingErrorRow(
|
||||||
onRetry = { state.eventSink(HealthChatProfileSectionEvents.Retry) },
|
onRetry = { state.eventSink(HealthChatProfileSectionEvent.Retry) },
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -147,7 +147,7 @@ private fun ProfileFieldRow(
|
|||||||
onClick: (() -> Unit)? = null,
|
onClick: (() -> Unit)? = null,
|
||||||
) {
|
) {
|
||||||
ListItem(
|
ListItem(
|
||||||
headlineContent = { Text(value) },
|
content = { Text(value) },
|
||||||
supportingContent = { Text(stringResource(labelRes)) },
|
supportingContent = { Text(stringResource(labelRes)) },
|
||||||
leadingContent = ListItemContent.Icon(IconSource.Vector(icon)),
|
leadingContent = ListItemContent.Icon(IconSource.Vector(icon)),
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
@@ -175,7 +175,7 @@ private fun LoadingErrorRow(
|
|||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
ListItem(
|
ListItem(
|
||||||
headlineContent = { Text(stringResource(HealthChatStrings.healthchat_profile_error_loading)) },
|
content = { Text(stringResource(HealthChatStrings.healthchat_profile_error_loading)) },
|
||||||
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Error())),
|
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Error())),
|
||||||
trailingContent = ListItemContent.Custom {
|
trailingContent = ListItemContent.Custom {
|
||||||
TextButton(
|
TextButton(
|
||||||
@@ -206,7 +206,7 @@ private fun String.withHttpScheme(): String {
|
|||||||
@PreviewsDayNight
|
@PreviewsDayNight
|
||||||
@Composable
|
@Composable
|
||||||
internal fun HealthChatProfileSectionViewPreview(
|
internal fun HealthChatProfileSectionViewPreview(
|
||||||
@PreviewParameter(HealthChatProfileSectionStateProvider::class) state: HealthChatProfileSectionState
|
@PreviewParameter(HealthChatProfileSectionStatePreviewParam::class) state: HealthChatProfileSectionState
|
||||||
) = ElementPreview {
|
) = ElementPreview {
|
||||||
HealthChatProfileSectionView(state = state)
|
HealthChatProfileSectionView(state = state)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ package io.element.android.features.healthchat.impl.status
|
|||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
|
||||||
open class HealthChatAccountStatusStateProvider : PreviewParameterProvider<HealthChatAccountStatusState> {
|
open class HealthChatAccountStatusStatePreviewParam : PreviewParameterProvider<HealthChatAccountStatusState> {
|
||||||
override val values: Sequence<HealthChatAccountStatusState>
|
override val values: Sequence<HealthChatAccountStatusState>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
HealthChatAccountStatusState(status = HealthChatAccountStatus.PendingApproval(serverMessage = null)),
|
HealthChatAccountStatusState(status = HealthChatAccountStatus.PendingApproval(serverMessage = null)),
|
||||||
+1
-1
@@ -74,7 +74,7 @@ fun HealthChatAccountStatusView(
|
|||||||
@PreviewsDayNight
|
@PreviewsDayNight
|
||||||
@Composable
|
@Composable
|
||||||
internal fun HealthChatAccountStatusViewPreview(
|
internal fun HealthChatAccountStatusViewPreview(
|
||||||
@PreviewParameter(HealthChatAccountStatusStateProvider::class) state: HealthChatAccountStatusState
|
@PreviewParameter(HealthChatAccountStatusStatePreviewParam::class) state: HealthChatAccountStatusState
|
||||||
) = ElementPreview {
|
) = ElementPreview {
|
||||||
HealthChatAccountStatusView(
|
HealthChatAccountStatusView(
|
||||||
state = state,
|
state = state,
|
||||||
|
|||||||
+9
-9
@@ -15,11 +15,11 @@ import io.element.android.features.healthchat.api.HealthChatApiException
|
|||||||
import io.element.android.features.healthchat.api.HealthChatDirectoryService
|
import io.element.android.features.healthchat.api.HealthChatDirectoryService
|
||||||
import io.element.android.features.healthchat.api.HealthChatMember
|
import io.element.android.features.healthchat.api.HealthChatMember
|
||||||
import io.element.android.features.healthchat.api.HealthChatMemberDirectory
|
import io.element.android.features.healthchat.api.HealthChatMemberDirectory
|
||||||
import io.element.android.features.healthchat.api.directory.MemberDirectoryEvents
|
import io.element.android.features.healthchat.api.directory.MemberDirectoryEvent
|
||||||
import io.element.android.features.healthchat.test.FakeHealthChatDirectoryService
|
import io.element.android.features.healthchat.test.FakeHealthChatDirectoryService
|
||||||
import io.element.android.features.healthchat.test.aHealthChatMember
|
import io.element.android.features.healthchat.test.aHealthChatMember
|
||||||
import io.element.android.features.invitepeople.test.FakeStartDMAction
|
|
||||||
import io.element.android.features.startchat.api.StartDMAction
|
import io.element.android.features.startchat.api.StartDMAction
|
||||||
|
import io.element.android.features.startchat.test.FakeStartDMAction
|
||||||
import io.element.android.libraries.architecture.AsyncAction
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
import io.element.android.libraries.architecture.AsyncData
|
import io.element.android.libraries.architecture.AsyncData
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
@@ -52,7 +52,7 @@ class MemberDirectoryPresenterTest {
|
|||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
assertThat(initialState.directory).isEqualTo(AsyncData.Uninitialized)
|
assertThat(initialState.directory).isEqualTo(AsyncData.Uninitialized)
|
||||||
searchLambda.assertions().isNeverCalled()
|
searchLambda.assertions().isNeverCalled()
|
||||||
initialState.eventSink(MemberDirectoryEvents.LoadIfNeeded)
|
initialState.eventSink(MemberDirectoryEvent.LoadIfNeeded)
|
||||||
val loadedState = consumeItemsUntilPredicate { it.directory is AsyncData.Success }.last()
|
val loadedState = consumeItemsUntilPredicate { it.directory is AsyncData.Success }.last()
|
||||||
assertThat(loadedState.directory.dataOrNull()).isEqualTo(aDirectory())
|
assertThat(loadedState.directory.dataOrNull()).isEqualTo(aDirectory())
|
||||||
searchLambda.assertions().isCalledOnce()
|
searchLambda.assertions().isCalledOnce()
|
||||||
@@ -72,7 +72,7 @@ class MemberDirectoryPresenterTest {
|
|||||||
)
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(MemberDirectoryEvents.LoadIfNeeded)
|
initialState.eventSink(MemberDirectoryEvent.LoadIfNeeded)
|
||||||
val loadedState = consumeItemsUntilPredicate { it.directory is AsyncData.Success }.last()
|
val loadedState = consumeItemsUntilPredicate { it.directory is AsyncData.Success }.last()
|
||||||
// Typing restarts the effect: intermediate values must be debounced away.
|
// Typing restarts the effect: intermediate values must be debounced away.
|
||||||
loadedState.searchQuery.setTextAndPlaceCursorAtEnd("M")
|
loadedState.searchQuery.setTextAndPlaceCursorAtEnd("M")
|
||||||
@@ -100,11 +100,11 @@ class MemberDirectoryPresenterTest {
|
|||||||
)
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(MemberDirectoryEvents.LoadIfNeeded)
|
initialState.eventSink(MemberDirectoryEvent.LoadIfNeeded)
|
||||||
val failedState = consumeItemsUntilPredicate { it.directory is AsyncData.Failure }.last()
|
val failedState = consumeItemsUntilPredicate { it.directory is AsyncData.Failure }.last()
|
||||||
// No stale fallback.
|
// No stale fallback.
|
||||||
assertThat((failedState.directory as AsyncData.Failure).prevData).isNull()
|
assertThat((failedState.directory as AsyncData.Failure).prevData).isNull()
|
||||||
failedState.eventSink(MemberDirectoryEvents.Refresh)
|
failedState.eventSink(MemberDirectoryEvent.Refresh)
|
||||||
val loadedState = consumeItemsUntilPredicate { it.directory is AsyncData.Success }.last()
|
val loadedState = consumeItemsUntilPredicate { it.directory is AsyncData.Success }.last()
|
||||||
assertThat(loadedState.directory.dataOrNull()).isEqualTo(aDirectory())
|
assertThat(loadedState.directory.dataOrNull()).isEqualTo(aDirectory())
|
||||||
}
|
}
|
||||||
@@ -127,7 +127,7 @@ class MemberDirectoryPresenterTest {
|
|||||||
)
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(MemberDirectoryEvents.LoadIfNeeded)
|
initialState.eventSink(MemberDirectoryEvent.LoadIfNeeded)
|
||||||
val state = consumeItemsUntilPredicate { it.directory is AsyncData.Success }.last()
|
val state = consumeItemsUntilPredicate { it.directory is AsyncData.Success }.last()
|
||||||
assertThat(state.isApproved).isFalse()
|
assertThat(state.isApproved).isFalse()
|
||||||
assertThat(state.pendingMessage).isEqualTo("Ihr Konto wird derzeit geprüft.")
|
assertThat(state.pendingMessage).isEqualTo("Ihr Konto wird derzeit geprüft.")
|
||||||
@@ -149,11 +149,11 @@ class MemberDirectoryPresenterTest {
|
|||||||
)
|
)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
initialState.eventSink(MemberDirectoryEvents.StartDm(MatrixUser(A_USER_ID)))
|
initialState.eventSink(MemberDirectoryEvent.StartDm(MatrixUser(A_USER_ID)))
|
||||||
val state = consumeItemsUntilPredicate { it.startDmActionState is AsyncAction.Success }.last()
|
val state = consumeItemsUntilPredicate { it.startDmActionState is AsyncAction.Success }.last()
|
||||||
assertThat((state.startDmActionState as AsyncAction.Success).data).isEqualTo(A_ROOM_ID)
|
assertThat((state.startDmActionState as AsyncAction.Success).data).isEqualTo(A_ROOM_ID)
|
||||||
executeLambda.assertions().isCalledOnce()
|
executeLambda.assertions().isCalledOnce()
|
||||||
state.eventSink(MemberDirectoryEvents.ClearStartDmState)
|
state.eventSink(MemberDirectoryEvent.ClearStartDmState)
|
||||||
val clearedState = consumeItemsUntilPredicate { it.startDmActionState is AsyncAction.Uninitialized }.last()
|
val clearedState = consumeItemsUntilPredicate { it.startDmActionState is AsyncAction.Uninitialized }.last()
|
||||||
assertThat(clearedState.startDmActionState).isEqualTo(AsyncAction.Uninitialized)
|
assertThat(clearedState.startDmActionState).isEqualTo(AsyncAction.Uninitialized)
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-12
@@ -18,7 +18,7 @@ import androidx.compose.ui.test.onNodeWithText
|
|||||||
import androidx.compose.ui.test.performClick
|
import androidx.compose.ui.test.performClick
|
||||||
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
|
||||||
import io.element.android.features.healthchat.api.HealthChatApiException
|
import io.element.android.features.healthchat.api.HealthChatApiException
|
||||||
import io.element.android.features.healthchat.api.directory.MemberDirectoryEvents
|
import io.element.android.features.healthchat.api.directory.MemberDirectoryEvent
|
||||||
import io.element.android.features.healthchat.api.directory.MemberDirectoryState
|
import io.element.android.features.healthchat.api.directory.MemberDirectoryState
|
||||||
import io.element.android.features.healthchat.api.directory.aDirectoryMember
|
import io.element.android.features.healthchat.api.directory.aDirectoryMember
|
||||||
import io.element.android.features.healthchat.api.directory.aMemberDirectory
|
import io.element.android.features.healthchat.api.directory.aMemberDirectory
|
||||||
@@ -37,19 +37,19 @@ import org.junit.Test
|
|||||||
class MemberDirectoryViewTest : RobolectricTest() {
|
class MemberDirectoryViewTest : RobolectricTest() {
|
||||||
@Test
|
@Test
|
||||||
fun `on composition LoadIfNeeded is emitted`() = runAndroidComposeUiTest<ComponentActivity> {
|
fun `on composition LoadIfNeeded is emitted`() = runAndroidComposeUiTest<ComponentActivity> {
|
||||||
val eventsRecorder = EventsRecorder<MemberDirectoryEvents>()
|
val eventsRecorder = EventsRecorder<MemberDirectoryEvent>()
|
||||||
setMemberDirectoryView(
|
setMemberDirectoryView(
|
||||||
state = aMemberDirectoryState(
|
state = aMemberDirectoryState(
|
||||||
directory = AsyncData.Uninitialized,
|
directory = AsyncData.Uninitialized,
|
||||||
eventSink = eventsRecorder,
|
eventSink = eventsRecorder,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
eventsRecorder.assertSingle(MemberDirectoryEvents.LoadIfNeeded)
|
eventsRecorder.assertSingle(MemberDirectoryEvent.LoadIfNeeded)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `clicking retry on the error state emits Refresh`() = runAndroidComposeUiTest<ComponentActivity> {
|
fun `clicking retry on the error state emits Refresh`() = runAndroidComposeUiTest<ComponentActivity> {
|
||||||
val eventsRecorder = EventsRecorder<MemberDirectoryEvents>()
|
val eventsRecorder = EventsRecorder<MemberDirectoryEvent>()
|
||||||
setMemberDirectoryView(
|
setMemberDirectoryView(
|
||||||
state = aMemberDirectoryState(
|
state = aMemberDirectoryState(
|
||||||
directory = AsyncData.Failure(HealthChatApiException.Http(500, "Fehler beim Laden der Benutzer")),
|
directory = AsyncData.Failure(HealthChatApiException.Http(500, "Fehler beim Laden der Benutzer")),
|
||||||
@@ -61,8 +61,8 @@ class MemberDirectoryViewTest : RobolectricTest() {
|
|||||||
clickOn(CommonStrings.action_retry)
|
clickOn(CommonStrings.action_retry)
|
||||||
eventsRecorder.assertList(
|
eventsRecorder.assertList(
|
||||||
listOf(
|
listOf(
|
||||||
MemberDirectoryEvents.LoadIfNeeded,
|
MemberDirectoryEvent.LoadIfNeeded,
|
||||||
MemberDirectoryEvents.Refresh,
|
MemberDirectoryEvent.Refresh,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ class MemberDirectoryViewTest : RobolectricTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `clicking start chat emits StartDm with the member as MatrixUser`() = runAndroidComposeUiTest<ComponentActivity> {
|
fun `clicking start chat emits StartDm with the member as MatrixUser`() = runAndroidComposeUiTest<ComponentActivity> {
|
||||||
val member = aDirectoryMember()
|
val member = aDirectoryMember()
|
||||||
val eventsRecorder = EventsRecorder<MemberDirectoryEvents>()
|
val eventsRecorder = EventsRecorder<MemberDirectoryEvent>()
|
||||||
setMemberDirectoryView(
|
setMemberDirectoryView(
|
||||||
state = aMemberDirectoryState(
|
state = aMemberDirectoryState(
|
||||||
directory = AsyncData.Success(aMemberDirectory(members = listOf(member))),
|
directory = AsyncData.Success(aMemberDirectory(members = listOf(member))),
|
||||||
@@ -82,8 +82,8 @@ class MemberDirectoryViewTest : RobolectricTest() {
|
|||||||
.performClick()
|
.performClick()
|
||||||
eventsRecorder.assertList(
|
eventsRecorder.assertList(
|
||||||
listOf(
|
listOf(
|
||||||
MemberDirectoryEvents.LoadIfNeeded,
|
MemberDirectoryEvent.LoadIfNeeded,
|
||||||
MemberDirectoryEvents.StartDm(member.toMatrixUser()),
|
MemberDirectoryEvent.StartDm(member.toMatrixUser()),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -91,7 +91,7 @@ class MemberDirectoryViewTest : RobolectricTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `clicking a member card opens the profile`() = runAndroidComposeUiTest<ComponentActivity> {
|
fun `clicking a member card opens the profile`() = runAndroidComposeUiTest<ComponentActivity> {
|
||||||
val member = aDirectoryMember()
|
val member = aDirectoryMember()
|
||||||
val eventsRecorder = EventsRecorder<MemberDirectoryEvents>(expectEvents = true)
|
val eventsRecorder = EventsRecorder<MemberDirectoryEvent>(expectEvents = true)
|
||||||
ensureCalledOnceWithParam(member.userId) { callback ->
|
ensureCalledOnceWithParam(member.userId) { callback ->
|
||||||
setMemberDirectoryView(
|
setMemberDirectoryView(
|
||||||
state = aMemberDirectoryState(
|
state = aMemberDirectoryState(
|
||||||
@@ -106,7 +106,7 @@ class MemberDirectoryViewTest : RobolectricTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `an unapproved account shows the pending banner and no search field`() = runAndroidComposeUiTest<ComponentActivity> {
|
fun `an unapproved account shows the pending banner and no search field`() = runAndroidComposeUiTest<ComponentActivity> {
|
||||||
val eventsRecorder = EventsRecorder<MemberDirectoryEvents>(expectEvents = true)
|
val eventsRecorder = EventsRecorder<MemberDirectoryEvent>(expectEvents = true)
|
||||||
setMemberDirectoryView(
|
setMemberDirectoryView(
|
||||||
state = aMemberDirectoryState(
|
state = aMemberDirectoryState(
|
||||||
directory = AsyncData.Success(
|
directory = AsyncData.Success(
|
||||||
@@ -127,7 +127,7 @@ class MemberDirectoryViewTest : RobolectricTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `hidden affordances are not rendered when their callbacks are null`() = runAndroidComposeUiTest<ComponentActivity> {
|
fun `hidden affordances are not rendered when their callbacks are null`() = runAndroidComposeUiTest<ComponentActivity> {
|
||||||
val eventsRecorder = EventsRecorder<MemberDirectoryEvents>(expectEvents = true)
|
val eventsRecorder = EventsRecorder<MemberDirectoryEvent>(expectEvents = true)
|
||||||
setMemberDirectoryView(
|
setMemberDirectoryView(
|
||||||
state = aMemberDirectoryState(eventSink = eventsRecorder),
|
state = aMemberDirectoryState(eventSink = eventsRecorder),
|
||||||
onMyProfileClick = null,
|
onMyProfileClick = null,
|
||||||
|
|||||||
+1
-1
@@ -106,7 +106,7 @@ class HealthChatProfileSectionPresenterTest {
|
|||||||
val presenter = createPresenter(isCurrentUser = false, directoryService = directoryService)
|
val presenter = createPresenter(isCurrentUser = false, directoryService = directoryService)
|
||||||
presenter.test {
|
presenter.test {
|
||||||
val failedState = consumeItemsUntilPredicate { it.profile is AsyncData.Failure }.last()
|
val failedState = consumeItemsUntilPredicate { it.profile is AsyncData.Failure }.last()
|
||||||
failedState.eventSink(HealthChatProfileSectionEvents.Retry)
|
failedState.eventSink(HealthChatProfileSectionEvent.Retry)
|
||||||
val state = consumeItemsUntilPredicate { it.profile is AsyncData.Success }.last()
|
val state = consumeItemsUntilPredicate { it.profile is AsyncData.Success }.last()
|
||||||
assertThat(state.profile).isEqualTo(AsyncData.Success(member))
|
assertThat(state.profile).isEqualTo(AsyncData.Success(member))
|
||||||
assertThat(callCount).isEqualTo(2)
|
assertThat(callCount).isEqualTo(2)
|
||||||
|
|||||||
+8
-8
@@ -30,7 +30,7 @@ import org.robolectric.Shadows.shadowOf
|
|||||||
class HealthChatProfileSectionViewTest : RobolectricTest() {
|
class HealthChatProfileSectionViewTest : RobolectricTest() {
|
||||||
@Test
|
@Test
|
||||||
fun `a loaded profile renders its fields with values`() = runAndroidComposeUiTest<ComponentActivity> {
|
fun `a loaded profile renders its fields with values`() = runAndroidComposeUiTest<ComponentActivity> {
|
||||||
val eventsRecorder = EventsRecorder<HealthChatProfileSectionEvents>(expectEvents = false)
|
val eventsRecorder = EventsRecorder<HealthChatProfileSectionEvent>(expectEvents = false)
|
||||||
setContent {
|
setContent {
|
||||||
HealthChatProfileSectionView(
|
HealthChatProfileSectionView(
|
||||||
state = aHealthChatProfileSectionState(
|
state = aHealthChatProfileSectionState(
|
||||||
@@ -50,7 +50,7 @@ class HealthChatProfileSectionViewTest : RobolectricTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `empty fields are omitted`() = runAndroidComposeUiTest<ComponentActivity> {
|
fun `empty fields are omitted`() = runAndroidComposeUiTest<ComponentActivity> {
|
||||||
val eventsRecorder = EventsRecorder<HealthChatProfileSectionEvents>(expectEvents = false)
|
val eventsRecorder = EventsRecorder<HealthChatProfileSectionEvent>(expectEvents = false)
|
||||||
setContent {
|
setContent {
|
||||||
HealthChatProfileSectionView(
|
HealthChatProfileSectionView(
|
||||||
state = aHealthChatProfileSectionState(
|
state = aHealthChatProfileSectionState(
|
||||||
@@ -77,7 +77,7 @@ class HealthChatProfileSectionViewTest : RobolectricTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `clicking the email row opens a mailto intent`() = runAndroidComposeUiTest<ComponentActivity> {
|
fun `clicking the email row opens a mailto intent`() = runAndroidComposeUiTest<ComponentActivity> {
|
||||||
val eventsRecorder = EventsRecorder<HealthChatProfileSectionEvents>(expectEvents = false)
|
val eventsRecorder = EventsRecorder<HealthChatProfileSectionEvent>(expectEvents = false)
|
||||||
setContent {
|
setContent {
|
||||||
HealthChatProfileSectionView(
|
HealthChatProfileSectionView(
|
||||||
state = aHealthChatProfileSectionState(
|
state = aHealthChatProfileSectionState(
|
||||||
@@ -94,7 +94,7 @@ class HealthChatProfileSectionViewTest : RobolectricTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `clicking the phone row opens a tel intent`() = runAndroidComposeUiTest<ComponentActivity> {
|
fun `clicking the phone row opens a tel intent`() = runAndroidComposeUiTest<ComponentActivity> {
|
||||||
val eventsRecorder = EventsRecorder<HealthChatProfileSectionEvents>(expectEvents = false)
|
val eventsRecorder = EventsRecorder<HealthChatProfileSectionEvent>(expectEvents = false)
|
||||||
setContent {
|
setContent {
|
||||||
HealthChatProfileSectionView(
|
HealthChatProfileSectionView(
|
||||||
state = aHealthChatProfileSectionState(
|
state = aHealthChatProfileSectionState(
|
||||||
@@ -110,7 +110,7 @@ class HealthChatProfileSectionViewTest : RobolectricTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `a loading state renders nothing`() = runAndroidComposeUiTest<ComponentActivity> {
|
fun `a loading state renders nothing`() = runAndroidComposeUiTest<ComponentActivity> {
|
||||||
val eventsRecorder = EventsRecorder<HealthChatProfileSectionEvents>(expectEvents = false)
|
val eventsRecorder = EventsRecorder<HealthChatProfileSectionEvent>(expectEvents = false)
|
||||||
setContent {
|
setContent {
|
||||||
HealthChatProfileSectionView(
|
HealthChatProfileSectionView(
|
||||||
state = aHealthChatProfileSectionState(
|
state = aHealthChatProfileSectionState(
|
||||||
@@ -124,7 +124,7 @@ class HealthChatProfileSectionViewTest : RobolectricTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `a NotFound failure renders nothing`() = runAndroidComposeUiTest<ComponentActivity> {
|
fun `a NotFound failure renders nothing`() = runAndroidComposeUiTest<ComponentActivity> {
|
||||||
val eventsRecorder = EventsRecorder<HealthChatProfileSectionEvents>(expectEvents = false)
|
val eventsRecorder = EventsRecorder<HealthChatProfileSectionEvent>(expectEvents = false)
|
||||||
val activity = requireNotNull(activity)
|
val activity = requireNotNull(activity)
|
||||||
setContent {
|
setContent {
|
||||||
HealthChatProfileSectionView(
|
HealthChatProfileSectionView(
|
||||||
@@ -139,7 +139,7 @@ class HealthChatProfileSectionViewTest : RobolectricTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `an error state shows a retry row which emits Retry`() = runAndroidComposeUiTest<ComponentActivity> {
|
fun `an error state shows a retry row which emits Retry`() = runAndroidComposeUiTest<ComponentActivity> {
|
||||||
val eventsRecorder = EventsRecorder<HealthChatProfileSectionEvents>()
|
val eventsRecorder = EventsRecorder<HealthChatProfileSectionEvent>()
|
||||||
setContent {
|
setContent {
|
||||||
HealthChatProfileSectionView(
|
HealthChatProfileSectionView(
|
||||||
state = aHealthChatProfileSectionState(
|
state = aHealthChatProfileSectionState(
|
||||||
@@ -149,6 +149,6 @@ class HealthChatProfileSectionViewTest : RobolectricTest() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
clickOn(CommonStrings.action_retry)
|
clickOn(CommonStrings.action_retry)
|
||||||
eventsRecorder.assertSingle(HealthChatProfileSectionEvents.Retry)
|
eventsRecorder.assertSingle(HealthChatProfileSectionEvent.Retry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -28,8 +28,10 @@ class HomeViewBackHandlingTest : RobolectricTest() {
|
|||||||
currentHomeNavigationBarItem = HomeNavigationBarItem.Members,
|
currentHomeNavigationBarItem = HomeNavigationBarItem.Members,
|
||||||
eventSink = eventsRecorder,
|
eventSink = eventsRecorder,
|
||||||
),
|
),
|
||||||
onRoomClick = {},
|
onRoomClick = { _, _ -> },
|
||||||
onSettingsClick = {},
|
onSettingsClick = {},
|
||||||
|
onAddAccountClick = {},
|
||||||
|
onSwitchToAccount = {},
|
||||||
onSetUpRecoveryClick = {},
|
onSetUpRecoveryClick = {},
|
||||||
onConfirmRecoveryKeyClick = {},
|
onConfirmRecoveryKeyClick = {},
|
||||||
onStartChatClick = {},
|
onStartChatClick = {},
|
||||||
@@ -58,8 +60,10 @@ class HomeViewBackHandlingTest : RobolectricTest() {
|
|||||||
currentHomeNavigationBarItem = HomeNavigationBarItem.Members,
|
currentHomeNavigationBarItem = HomeNavigationBarItem.Members,
|
||||||
eventSink = eventsRecorder,
|
eventSink = eventsRecorder,
|
||||||
),
|
),
|
||||||
onRoomClick = {},
|
onRoomClick = { _, _ -> },
|
||||||
onSettingsClick = {},
|
onSettingsClick = {},
|
||||||
|
onAddAccountClick = {},
|
||||||
|
onSwitchToAccount = {},
|
||||||
onSetUpRecoveryClick = {},
|
onSetUpRecoveryClick = {},
|
||||||
onConfirmRecoveryKeyClick = {},
|
onConfirmRecoveryKeyClick = {},
|
||||||
onStartChatClick = {},
|
onStartChatClick = {},
|
||||||
|
|||||||
Reference in New Issue
Block a user