Skip to content

Commit 14082bc

Browse files
committed
feat(join by alias) : add tests
1 parent c220fb0 commit 14082bc

File tree

5 files changed

+259
-1
lines changed

5 files changed

+259
-1
lines changed

features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressStateProvider.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ open class JoinRoomByAddressStateProvider : PreviewParameterProvider<JoinRoomByA
2929
fun aJoinRoomByAddressState(
3030
address: String = "",
3131
addressState: RoomAddressState = RoomAddressState.Unknown,
32+
eventSink: (JoinRoomByAddressEvents) -> Unit = {},
3233
) = JoinRoomByAddressState(
3334
address = address,
3435
addressState = addressState,
35-
eventSink = {}
36+
eventSink = eventSink
3637
)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2025 New Vector Ltd.
3+
*
4+
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
5+
* Please see LICENSE files in the repository root for full details.
6+
*/
7+
8+
package io.element.android.features.createroom.impl
9+
10+
import io.element.android.features.createroom.CreateRoomNavigator
11+
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
12+
13+
class FakeCreateRoomNavigator(
14+
private val openRoomLambda: (roomIdOrAlias: RoomIdOrAlias, serverNames: List<String>) -> Unit = { _, _ -> },
15+
private val createNewRoomLambda: () -> Unit = {},
16+
private val showJoinRoomByAddressLambda: () -> Unit = {},
17+
private val dismissJoinRoomByAddressLambda: () -> Unit = {},
18+
19+
) : CreateRoomNavigator {
20+
override fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias, serverNames: List<String>) {
21+
openRoomLambda(roomIdOrAlias, serverNames)
22+
}
23+
24+
override fun onCreateNewRoom() {
25+
createNewRoomLambda()
26+
}
27+
28+
override fun onShowJoinRoomByAddress() {
29+
showJoinRoomByAddressLambda()
30+
}
31+
32+
override fun onDismissJoinRoomByAddress() {
33+
dismissJoinRoomByAddressLambda()
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
* Copyright 2025 New Vector Ltd.
3+
*
4+
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
5+
* Please see LICENSE files in the repository root for full details.
6+
*/
7+
8+
package io.element.android.features.createroom.impl.joinbyaddress
9+
10+
import com.google.common.truth.Truth.assertThat
11+
import io.element.android.features.createroom.CreateRoomNavigator
12+
import io.element.android.features.createroom.impl.FakeCreateRoomNavigator
13+
import io.element.android.libraries.matrix.api.MatrixClient
14+
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
15+
import io.element.android.libraries.matrix.api.room.alias.RoomAliasHelper
16+
import io.element.android.libraries.matrix.test.FakeMatrixClient
17+
import io.element.android.libraries.matrix.test.room.alias.FakeRoomAliasHelper
18+
import io.element.android.tests.testutils.lambda.assert
19+
import io.element.android.tests.testutils.lambda.lambdaRecorder
20+
import io.element.android.tests.testutils.test
21+
import kotlinx.coroutines.test.runTest
22+
import org.junit.Test
23+
24+
class JoinRoomByAddressPresenterTest {
25+
26+
@Test
27+
fun `present - initial state`() = runTest {
28+
val presenter = createJoinRoomByAddressPresenter()
29+
presenter.test {
30+
with(awaitItem()) {
31+
assertThat(address).isEmpty()
32+
assertThat(addressState).isEqualTo(RoomAddressState.Unknown)
33+
}
34+
}
35+
}
36+
37+
@Test
38+
fun `present - invalid address`() = runTest {
39+
val presenter = createJoinRoomByAddressPresenter(
40+
roomAliasHelper = FakeRoomAliasHelper(
41+
isRoomAliasValidLambda = { false }
42+
)
43+
)
44+
presenter.test {
45+
with(awaitItem()) {
46+
eventSink(JoinRoomByAddressEvents.UpdateAddress("invalid_address"))
47+
}
48+
with(awaitItem()) {
49+
assertThat(address).isEqualTo("invalid_address")
50+
assertThat(addressState).isEqualTo(RoomAddressState.Unknown)
51+
eventSink(JoinRoomByAddressEvents.Continue)
52+
}
53+
// The address should be marked as invalid only after the user tries to continue
54+
with(awaitItem()) {
55+
assertThat(address).isEqualTo("invalid_address")
56+
assertThat(addressState).isEqualTo(RoomAddressState.Invalid)
57+
}
58+
}
59+
}
60+
61+
@Test
62+
fun `present - room found`() = runTest {
63+
val openRoomLambda = lambdaRecorder<RoomIdOrAlias, List<String>, Unit> { _, _ -> }
64+
val dismissJoinRoomByAddressLambda = lambdaRecorder<Unit> { }
65+
val navigator = FakeCreateRoomNavigator(
66+
openRoomLambda = openRoomLambda,
67+
dismissJoinRoomByAddressLambda = dismissJoinRoomByAddressLambda
68+
)
69+
val presenter = createJoinRoomByAddressPresenter(navigator = navigator)
70+
presenter.test {
71+
with(awaitItem()) {
72+
eventSink(JoinRoomByAddressEvents.UpdateAddress("#room_found:matrix.org"))
73+
}
74+
with(awaitItem()) {
75+
assertThat(address).isEqualTo("#room_found:matrix.org")
76+
assertThat(addressState).isEqualTo(RoomAddressState.Unknown)
77+
}
78+
with(awaitItem()) {
79+
assertThat(address).isEqualTo("#room_found:matrix.org")
80+
assertThat(addressState).isInstanceOf(RoomAddressState.RoomFound::class.java)
81+
eventSink(JoinRoomByAddressEvents.Continue)
82+
}
83+
assert(openRoomLambda).isCalledOnce()
84+
assert(dismissJoinRoomByAddressLambda).isCalledOnce()
85+
}
86+
}
87+
88+
@Test
89+
fun `present - room not found`() = runTest {
90+
val presenter = createJoinRoomByAddressPresenter(
91+
matrixClient = FakeMatrixClient(
92+
resolveRoomAliasResult = { Result.failure(RuntimeException()) }
93+
)
94+
)
95+
presenter.test {
96+
with(awaitItem()) {
97+
eventSink(JoinRoomByAddressEvents.UpdateAddress("#room_not_found:matrix.org"))
98+
}
99+
with(awaitItem()) {
100+
assertThat(address).isEqualTo("#room_not_found:matrix.org")
101+
assertThat(addressState).isEqualTo(RoomAddressState.Unknown)
102+
eventSink(JoinRoomByAddressEvents.Continue)
103+
}
104+
with(awaitItem()) {
105+
assertThat(address).isEqualTo("#room_not_found:matrix.org")
106+
assertThat(addressState).isEqualTo(RoomAddressState.Resolving)
107+
}
108+
with(awaitItem()) {
109+
assertThat(address).isEqualTo("#room_not_found:matrix.org")
110+
assertThat(addressState).isEqualTo(RoomAddressState.RoomNotFound)
111+
}
112+
}
113+
}
114+
115+
@Test
116+
fun `present - dismiss`() = runTest {
117+
val dismissJoinRoomByAddressLambda = lambdaRecorder<Unit> { }
118+
val navigator = FakeCreateRoomNavigator(
119+
dismissJoinRoomByAddressLambda = dismissJoinRoomByAddressLambda
120+
)
121+
val presenter = createJoinRoomByAddressPresenter(navigator = navigator)
122+
presenter.test {
123+
with(awaitItem()) {
124+
eventSink(JoinRoomByAddressEvents.Dismiss)
125+
}
126+
assert(dismissJoinRoomByAddressLambda).isCalledOnce()
127+
}
128+
}
129+
130+
private fun createJoinRoomByAddressPresenter(
131+
navigator: CreateRoomNavigator = FakeCreateRoomNavigator(),
132+
matrixClient: MatrixClient = FakeMatrixClient(),
133+
roomAliasHelper: RoomAliasHelper = FakeRoomAliasHelper(),
134+
): JoinRoomByAddressPresenter {
135+
return JoinRoomByAddressPresenter(
136+
navigator = navigator,
137+
client = matrixClient,
138+
roomAliasHelper = roomAliasHelper,
139+
)
140+
}
141+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2025 New Vector Ltd.
3+
*
4+
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
5+
* Please see LICENSE files in the repository root for full details.
6+
*/
7+
8+
package io.element.android.features.createroom.impl.joinbyaddress
9+
10+
import androidx.activity.ComponentActivity
11+
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
12+
import androidx.compose.ui.test.junit4.createAndroidComposeRule
13+
import androidx.compose.ui.test.onNodeWithText
14+
import androidx.compose.ui.test.performTextInput
15+
import androidx.test.ext.junit.runners.AndroidJUnit4
16+
import io.element.android.features.createroom.impl.R
17+
import io.element.android.libraries.ui.strings.CommonStrings
18+
import io.element.android.tests.testutils.EventsRecorder
19+
import io.element.android.tests.testutils.clickOn
20+
import org.junit.Rule
21+
import org.junit.Test
22+
import org.junit.rules.TestRule
23+
import org.junit.runner.RunWith
24+
25+
@RunWith(AndroidJUnit4::class)
26+
class JoinRoomByAddressViewTest {
27+
28+
@get:Rule
29+
val rule = createAndroidComposeRule<ComponentActivity>()
30+
31+
@Test
32+
fun `entering text emits the expected event`() {
33+
val eventsRecorder = EventsRecorder<JoinRoomByAddressEvents>()
34+
rule.setJoinRoomByAddressView(
35+
aJoinRoomByAddressState(
36+
eventSink = eventsRecorder,
37+
)
38+
)
39+
val text = rule.activity.getString(R.string.screen_start_chat_join_room_by_address_action)
40+
rule.onNodeWithText(text).performTextInput("#address:matrix.org")
41+
eventsRecorder.assertSingle(JoinRoomByAddressEvents.UpdateAddress("#address:matrix.org"))
42+
}
43+
44+
@Test
45+
fun `clicking on continue emits the expected event`() {
46+
val eventsRecorder = EventsRecorder<JoinRoomByAddressEvents>()
47+
rule.setJoinRoomByAddressView(
48+
aJoinRoomByAddressState(
49+
eventSink = eventsRecorder,
50+
)
51+
)
52+
rule.clickOn(CommonStrings.action_continue)
53+
eventsRecorder.assertSingle(JoinRoomByAddressEvents.Continue)
54+
}
55+
56+
}
57+
58+
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setJoinRoomByAddressView(
59+
state: JoinRoomByAddressState,
60+
) {
61+
setContent {
62+
JoinRoomByAddressView(state = state)
63+
}
64+
}

features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootViewTest.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,21 @@ class CreateRoomRootViewTest {
101101
rule.onNodeWithText(firstRoom.matrixUser.getBestName()).performClick()
102102
}
103103
}
104+
105+
@Config(qualifiers = "h1024dp")
106+
@Test
107+
fun `clicking on Join room by address invokes the expected callback`() {
108+
val eventsRecorder = EventsRecorder<CreateRoomRootEvents>(expectEvents = false)
109+
ensureCalledOnce {
110+
rule.setCreateRoomRootView(
111+
aCreateRoomRootState(
112+
eventSink = eventsRecorder,
113+
),
114+
onJoinRoomByAddressClick = it
115+
)
116+
rule.clickOn(R.string.screen_start_chat_join_room_by_address_action)
117+
}
118+
}
104119
}
105120

106121
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setCreateRoomRootView(
@@ -109,6 +124,7 @@ private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setCreat
109124
onNewRoomClick: () -> Unit = EnsureNeverCalled(),
110125
onOpenDM: (RoomId) -> Unit = EnsureNeverCalledWithParam(),
111126
onInviteFriendsClick: () -> Unit = EnsureNeverCalled(),
127+
onJoinRoomByAddressClick: () -> Unit = EnsureNeverCalled(),
112128
) {
113129
setContent {
114130
CreateRoomRootView(
@@ -117,6 +133,7 @@ private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setCreat
117133
onNewRoomClick = onNewRoomClick,
118134
onOpenDM = onOpenDM,
119135
onInviteFriendsClick = onInviteFriendsClick,
136+
onJoinByAddressClick = onJoinRoomByAddressClick
120137
)
121138
}
122139
}

0 commit comments

Comments
 (0)