Skip to content

Commit 62c07fa

Browse files
authored
Merge pull request #7322 from vector-im/feature/nfe/app_layout_tests
new app layout home screen unit tests
2 parents c76a9c1 + 7badf77 commit 62c07fa

File tree

8 files changed

+409
-0
lines changed

8 files changed

+409
-0
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright (c) 2022 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package im.vector.app.features.home
18+
19+
import com.airbnb.mvrx.test.MavericksTestRule
20+
import im.vector.app.features.home.room.list.home.invites.InvitesAction
21+
import im.vector.app.features.home.room.list.home.invites.InvitesViewEvents
22+
import im.vector.app.features.home.room.list.home.invites.InvitesViewModel
23+
import im.vector.app.features.home.room.list.home.invites.InvitesViewState
24+
import im.vector.app.test.fakes.FakeDrawableProvider
25+
import im.vector.app.test.fakes.FakeSession
26+
import im.vector.app.test.fakes.FakeStringProvider
27+
import im.vector.app.test.fixtures.RoomSummaryFixture
28+
import im.vector.app.test.test
29+
import io.mockk.coEvery
30+
import io.mockk.coVerify
31+
import io.mockk.every
32+
import io.mockk.mockk
33+
import io.mockk.mockkStatic
34+
import kotlinx.coroutines.test.runTest
35+
import org.junit.Before
36+
import org.junit.Rule
37+
import org.junit.Test
38+
import org.matrix.android.sdk.api.session.room.model.Membership
39+
40+
class InvitesViewModelTest {
41+
42+
@get:Rule
43+
val mavericksTestRule = MavericksTestRule()
44+
45+
private val fakeSession = FakeSession()
46+
private val fakeStringProvider = FakeStringProvider()
47+
private val fakeDrawableProvider = FakeDrawableProvider()
48+
49+
private var initialState = InvitesViewState()
50+
private lateinit var viewModel: InvitesViewModel
51+
52+
private val anInvite = RoomSummaryFixture.aRoomSummary("invite")
53+
54+
@Before
55+
fun setUp() {
56+
mockkStatic("org.matrix.android.sdk.flow.FlowSessionKt")
57+
58+
every {
59+
fakeSession.fakeRoomService.getPagedRoomSummariesLive(
60+
queryParams = match {
61+
it.memberships == listOf(Membership.INVITE)
62+
},
63+
pagedListConfig = any(),
64+
sortOrder = any()
65+
)
66+
} returns mockk()
67+
68+
viewModelWith(initialState)
69+
}
70+
71+
@Test
72+
fun `when invite accepted then membership map is updated and open event posted`() = runTest {
73+
val test = viewModel.test()
74+
75+
viewModel.handle(InvitesAction.AcceptInvitation(anInvite))
76+
77+
test.assertEvents(
78+
InvitesViewEvents.OpenRoom(
79+
roomSummary = anInvite,
80+
shouldCloseInviteView = false,
81+
isInviteAlreadySelected = true
82+
)
83+
).finish()
84+
}
85+
86+
@Test
87+
fun `when invite rejected then membership map is updated and open event posted`() = runTest {
88+
coEvery { fakeSession.roomService().leaveRoom(any(), any()) } returns Unit
89+
90+
viewModel.handle(InvitesAction.RejectInvitation(anInvite))
91+
92+
coVerify {
93+
fakeSession.roomService().leaveRoom(anInvite.roomId)
94+
}
95+
}
96+
97+
private fun viewModelWith(state: InvitesViewState) {
98+
InvitesViewModel(
99+
state,
100+
session = fakeSession,
101+
stringProvider = fakeStringProvider.instance,
102+
drawableProvider = fakeDrawableProvider.instance,
103+
).also {
104+
viewModel = it
105+
initialState = state
106+
}
107+
}
108+
}
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/*
2+
* Copyright (c) 2022 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package im.vector.app.features.home
18+
19+
import android.widget.ImageView
20+
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
21+
import com.airbnb.mvrx.test.MavericksTestRule
22+
import im.vector.app.R
23+
import im.vector.app.core.platform.StateView
24+
import im.vector.app.features.displayname.getBestName
25+
import im.vector.app.features.home.room.list.home.HomeRoomListAction
26+
import im.vector.app.features.home.room.list.home.HomeRoomListViewModel
27+
import im.vector.app.features.home.room.list.home.HomeRoomListViewState
28+
import im.vector.app.features.home.room.list.home.header.HomeRoomFilter
29+
import im.vector.app.test.fakes.FakeAnalyticsTracker
30+
import im.vector.app.test.fakes.FakeDrawableProvider
31+
import im.vector.app.test.fakes.FakeHomeLayoutPreferencesStore
32+
import im.vector.app.test.fakes.FakeSession
33+
import im.vector.app.test.fakes.FakeSpaceStateHandler
34+
import im.vector.app.test.fakes.FakeStringProvider
35+
import im.vector.app.test.fixtures.RoomSummaryFixture.aRoomSummary
36+
import im.vector.app.test.test
37+
import io.mockk.every
38+
import io.mockk.mockkStatic
39+
import kotlinx.coroutines.flow.flowOf
40+
import kotlinx.coroutines.test.runTest
41+
import org.junit.Before
42+
import org.junit.Rule
43+
import org.junit.Test
44+
import org.matrix.android.sdk.api.query.SpaceFilter
45+
import org.matrix.android.sdk.api.session.getUserOrDefault
46+
import org.matrix.android.sdk.api.session.room.model.Membership
47+
import org.matrix.android.sdk.api.util.Optional
48+
import org.matrix.android.sdk.api.util.toMatrixItem
49+
import org.matrix.android.sdk.flow.FlowSession
50+
51+
class RoomsListViewModelTest {
52+
53+
@get:Rule
54+
val mavericksTestRule = MavericksTestRule()
55+
56+
@get:Rule
57+
var rule = InstantTaskExecutorRule()
58+
59+
private val fakeSession = FakeSession()
60+
private val fakeAnalyticsTracker = FakeAnalyticsTracker()
61+
private val fakeStringProvider = FakeStringProvider()
62+
private val fakeDrawableProvider = FakeDrawableProvider()
63+
private val fakeSpaceStateHandler = FakeSpaceStateHandler()
64+
private val fakeHomeLayoutPreferencesStore = FakeHomeLayoutPreferencesStore()
65+
66+
private var initialState = HomeRoomListViewState()
67+
private lateinit var viewModel: HomeRoomListViewModel
68+
private lateinit var fakeFLowSession: FlowSession
69+
70+
@Before
71+
fun setUp() {
72+
mockkStatic("org.matrix.android.sdk.flow.FlowSessionKt")
73+
fakeFLowSession = fakeSession.givenFlowSession()
74+
75+
every { fakeSpaceStateHandler.getSelectedSpaceFlow() } returns flowOf(Optional.empty())
76+
every { fakeSpaceStateHandler.getCurrentSpace() } returns null
77+
every { fakeFLowSession.liveRoomSummaries(any(), any()) } returns flowOf(emptyList())
78+
79+
val roomA = aRoomSummary("room_a")
80+
val roomB = aRoomSummary("room_b")
81+
val roomC = aRoomSummary("room_c")
82+
val allRooms = listOf(roomA, roomB, roomC)
83+
84+
every {
85+
fakeFLowSession.liveRoomSummaries(
86+
match {
87+
it.roomCategoryFilter == null &&
88+
it.roomTagQueryFilter == null &&
89+
it.memberships == listOf(Membership.JOIN) &&
90+
it.spaceFilter is SpaceFilter.NoFilter
91+
}, any()
92+
)
93+
} returns flowOf(allRooms)
94+
95+
viewModelWith(initialState)
96+
}
97+
98+
@Test
99+
fun `when recents are enabled then updates state`() = runTest {
100+
val fakeFLowSession = fakeSession.givenFlowSession()
101+
every { fakeFLowSession.liveRoomSummaries(any()) } returns flowOf(emptyList())
102+
val test = viewModel.test()
103+
104+
val roomA = aRoomSummary("room_a")
105+
val roomB = aRoomSummary("room_b")
106+
val roomC = aRoomSummary("room_c")
107+
val recentRooms = listOf(roomA, roomB, roomC)
108+
109+
every { fakeFLowSession.liveBreadcrumbs(any()) } returns flowOf(recentRooms)
110+
fakeHomeLayoutPreferencesStore.givenRecentsEnabled(true)
111+
112+
val userName = fakeSession.getUserOrDefault(fakeSession.myUserId).toMatrixItem().getBestName()
113+
val allEmptyState = StateView.State.Empty(
114+
title = fakeStringProvider.instance.getString(R.string.home_empty_no_rooms_title, userName),
115+
message = fakeStringProvider.instance.getString(R.string.home_empty_no_rooms_message),
116+
image = fakeDrawableProvider.instance.getDrawable(R.drawable.ill_empty_all_chats),
117+
isBigImage = true
118+
)
119+
120+
test.assertLatestState(
121+
initialState.copy(emptyState = allEmptyState, headersData = initialState.headersData.copy(recents = recentRooms))
122+
)
123+
}
124+
125+
@Test
126+
fun `when filter tabs are enabled then updates state`() = runTest {
127+
val test = viewModel.test()
128+
129+
fakeHomeLayoutPreferencesStore.givenFiltersEnabled(true)
130+
131+
val filtersData = mutableListOf(
132+
HomeRoomFilter.ALL,
133+
HomeRoomFilter.UNREADS
134+
)
135+
136+
val userName = fakeSession.getUserOrDefault(fakeSession.myUserId).toMatrixItem().getBestName()
137+
val allEmptyState = StateView.State.Empty(
138+
title = fakeStringProvider.instance.getString(R.string.home_empty_no_rooms_title, userName),
139+
message = fakeStringProvider.instance.getString(R.string.home_empty_no_rooms_message),
140+
image = fakeDrawableProvider.instance.getDrawable(R.drawable.ill_empty_all_chats),
141+
isBigImage = true
142+
)
143+
144+
test.assertLatestState(
145+
initialState.copy(emptyState = allEmptyState, headersData = initialState.headersData.copy(filtersList = filtersData))
146+
)
147+
}
148+
149+
@Test
150+
fun `when filter tab is selected then updates state`() = runTest {
151+
val test = viewModel.test()
152+
153+
val aFilter = HomeRoomFilter.UNREADS
154+
viewModel.handle(HomeRoomListAction.ChangeRoomFilter(filter = aFilter))
155+
156+
val unreadsEmptyState = StateView.State.Empty(
157+
title = fakeStringProvider.instance.getString(R.string.home_empty_no_unreads_title),
158+
message = fakeStringProvider.instance.getString(R.string.home_empty_no_unreads_message),
159+
image = fakeDrawableProvider.instance.getDrawable(R.drawable.ill_empty_unreads),
160+
isBigImage = true,
161+
imageScaleType = ImageView.ScaleType.CENTER_INSIDE
162+
)
163+
164+
test.assertLatestState(
165+
initialState.copy(emptyState = unreadsEmptyState, headersData = initialState.headersData.copy(currentFilter = aFilter))
166+
)
167+
}
168+
169+
private fun viewModelWith(state: HomeRoomListViewState) {
170+
HomeRoomListViewModel(
171+
state,
172+
session = fakeSession,
173+
spaceStateHandler = fakeSpaceStateHandler,
174+
preferencesStore = fakeHomeLayoutPreferencesStore.instance,
175+
stringProvider = fakeStringProvider.instance,
176+
drawableProvider = fakeDrawableProvider.instance,
177+
analyticsTracker = fakeAnalyticsTracker
178+
179+
).also {
180+
viewModel = it
181+
initialState = state
182+
}
183+
}
184+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (c) 2021 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package im.vector.app.test.fakes
18+
19+
import im.vector.app.core.resources.DrawableProvider
20+
import io.mockk.every
21+
import io.mockk.mockk
22+
23+
class FakeDrawableProvider {
24+
val instance = mockk<DrawableProvider>()
25+
26+
init {
27+
every { instance.getDrawable(any()) } returns mockk()
28+
every { instance.getDrawable(any(), any()) } returns mockk()
29+
}
30+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2022 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package im.vector.app.test.fakes
18+
19+
import im.vector.app.features.home.room.list.home.HomeLayoutPreferencesStore
20+
import io.mockk.every
21+
import io.mockk.mockk
22+
import kotlinx.coroutines.flow.MutableSharedFlow
23+
24+
class FakeHomeLayoutPreferencesStore {
25+
26+
private val _areRecentsEnabledFlow = MutableSharedFlow<Boolean>()
27+
private val _areFiltersEnabledFlow = MutableSharedFlow<Boolean>()
28+
private val _isAZOrderingEnabledFlow = MutableSharedFlow<Boolean>()
29+
30+
val instance = mockk<HomeLayoutPreferencesStore>(relaxed = true) {
31+
every { areRecentsEnabledFlow } returns _areRecentsEnabledFlow
32+
every { areFiltersEnabledFlow } returns _areFiltersEnabledFlow
33+
every { isAZOrderingEnabledFlow } returns _isAZOrderingEnabledFlow
34+
}
35+
36+
suspend fun givenRecentsEnabled(enabled: Boolean) {
37+
_areRecentsEnabledFlow.emit(enabled)
38+
}
39+
40+
suspend fun givenFiltersEnabled(enabled: Boolean) {
41+
_areFiltersEnabledFlow.emit(enabled)
42+
}
43+
}

vector/src/test/java/im/vector/app/test/fakes/FakeRoomService.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,8 @@ class FakeRoomService(
3030
fun getRoomSummaryReturns(roomSummary: RoomSummary?) {
3131
every { getRoomSummary(any()) } returns roomSummary
3232
}
33+
34+
fun set(roomSummary: RoomSummary?) {
35+
every { getRoomSummary(any()) } returns roomSummary
36+
}
3337
}

0 commit comments

Comments
 (0)