From 62b2ecd338e2cc81d712203e3b52f3a10ca7b131 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Mon, 22 Jul 2024 21:04:42 +0200 Subject: [PATCH] Add tests for fetching contacts Signed-off-by: sowjanyakch --- app/build.gradle | 5 ++ .../talk/contacts/ContactsActivityCompose.kt | 1 + .../talk/contacts/ContactsRepository.kt | 1 + .../talk/contacts/ContactsRepositoryImpl.kt | 8 +++ .../talk/contacts/ContactsViewModel.kt | 15 +----- .../talk/contacts/ContactsViewModelTest.kt | 53 +++++++++++++++++++ .../contacts/apiService/FakeApiService.kt | 27 ---------- .../talk/contacts/apiService/FakeItem.kt | 36 ++++++++++++- .../repository/FakeRepositoryError.kt | 8 ++- .../repository/FakeRepositorySuccess.kt | 7 ++- gradle/verification-metadata.xml | 30 ++++++++++- 11 files changed, 145 insertions(+), 46 deletions(-) create mode 100644 app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt delete mode 100644 app/src/test/java/com/nextcloud/talk/contacts/apiService/FakeApiService.kt diff --git a/app/build.gradle b/app/build.gradle index 0a8b8285f..364e6ee4b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -158,6 +158,8 @@ ext { workVersion = "2.9.1" espressoVersion = "3.6.1" media3_version = "1.4.0" + coroutines_version = "1.3.9" + mockitoKotlinVersion = "4.1.0" } configurations.configureEach { @@ -338,6 +340,9 @@ dependencies { testImplementation("junit:junit:4.13.2") androidTestImplementation(platform("androidx.compose:compose-bom:2024.06.00")) androidTestImplementation("androidx.compose.ui:ui-test-junit4") + testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion" + testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version" + } tasks.register('installGitHooks', Copy) { diff --git a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt index a5b111952..582cdf929 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt @@ -170,6 +170,7 @@ fun ContactsItem(contacts: List, contactsViewModel: ContactsVi } items(contactsForInitial) { contact -> ContactItemRow(contact = contact, contactsViewModel = contactsViewModel, context = context) + Log.d(CompanionClass.TAG, "Contacts:$contact") } } } diff --git a/app/src/main/java/com/nextcloud/talk/contacts/ContactsRepository.kt b/app/src/main/java/com/nextcloud/talk/contacts/ContactsRepository.kt index 1a3347251..8655b79e1 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/ContactsRepository.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsRepository.kt @@ -13,4 +13,5 @@ import com.nextcloud.talk.models.json.conversations.RoomOverall interface ContactsRepository { suspend fun getContacts(searchQuery: String?, shareTypes: List): AutocompleteOverall suspend fun createRoom(roomType: String, sourceType: String, userId: String, conversationName: String?): RoomOverall + fun getImageUri(avatarId: String, requestBigSize: Boolean): String } diff --git a/app/src/main/java/com/nextcloud/talk/contacts/ContactsRepositoryImpl.kt b/app/src/main/java/com/nextcloud/talk/contacts/ContactsRepositoryImpl.kt index dbe8be1c5..6fcd27512 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/ContactsRepositoryImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsRepositoryImpl.kt @@ -64,4 +64,12 @@ class ContactsRepositoryImpl( ) return response } + + override fun getImageUri(avatarId: String, requestBigSize: Boolean): String { + return ApiUtils.getUrlForAvatar( + _currentUser.baseUrl, + avatarId, + requestBigSize + ) + } } diff --git a/app/src/main/java/com/nextcloud/talk/contacts/ContactsViewModel.kt b/app/src/main/java/com/nextcloud/talk/contacts/ContactsViewModel.kt index 955e2da86..7b0a2e450 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/ContactsViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsViewModel.kt @@ -9,27 +9,21 @@ package com.nextcloud.talk.contacts import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser import com.nextcloud.talk.models.json.conversations.Conversation -import com.nextcloud.talk.users.UserManager -import com.nextcloud.talk.utils.ApiUtils import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import javax.inject.Inject class ContactsViewModel @Inject constructor( - private val repository: ContactsRepository, - private val userManager: UserManager + private val repository: ContactsRepository ) : ViewModel() { private val _contactsViewState = MutableStateFlow(ContactsUiState.None) val contactsViewState: StateFlow = _contactsViewState private val _roomViewState = MutableStateFlow(RoomUiState.None) val roomViewState: StateFlow = _roomViewState - private val _currentUser = userManager.currentUser.blockingGet() - val currentUser: User = _currentUser private val _searchQuery = MutableStateFlow("") val searchQuery: StateFlow = _searchQuery private val shareTypes: MutableList = mutableListOf(ShareType.User.shareType) @@ -86,13 +80,8 @@ class ContactsViewModel @Inject constructor( } } } - fun getImageUri(avatarId: String, requestBigSize: Boolean): String { - return ApiUtils.getUrlForAvatar( - _currentUser.baseUrl, - avatarId, - requestBigSize - ) + return repository.getImageUri(avatarId, requestBigSize) } } diff --git a/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt b/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt new file mode 100644 index 000000000..feabd9230 --- /dev/null +++ b/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt @@ -0,0 +1,53 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2024 Your Name + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.contacts + +import com.nextcloud.talk.contacts.apiService.FakeItem +import com.nextcloud.talk.contacts.repository.FakeRepositorySuccess +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestDispatcher +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain +import org.junit.After +import org.junit.Before +import org.junit.Test + +@OptIn(ExperimentalCoroutinesApi::class) +class ContactsViewModelTest { + private lateinit var viewModel: ContactsViewModel + private val repository: ContactsRepository = FakeRepositorySuccess() + + val dispatcher: TestDispatcher = UnconfinedTestDispatcher() + + @Before + fun setup() { + Dispatchers.setMain(dispatcher) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Before + fun setUp() { + viewModel = ContactsViewModel(repository) + } + + @Test + fun `fetch contacts`() = + runTest { + viewModel.getContactsFromSearchParams() + assert(viewModel.contactsViewState.value is ContactsUiState.Success) + val successState = viewModel.contactsViewState.value as ContactsUiState.Success + assert(successState.contacts == FakeItem.contacts) + } +} diff --git a/app/src/test/java/com/nextcloud/talk/contacts/apiService/FakeApiService.kt b/app/src/test/java/com/nextcloud/talk/contacts/apiService/FakeApiService.kt deleted file mode 100644 index 37ffad6fe..000000000 --- a/app/src/test/java/com/nextcloud/talk/contacts/apiService/FakeApiService.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Nextcloud Talk - Android Client - * - * SPDX-FileCopyrightText: 2024 Your Name - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package com.nextcloud.talk.contacts.apiService - -import com.nextcloud.talk.api.NcApiCoroutines -import com.nextcloud.talk.models.json.autocomplete.AutocompleteOverall -import com.nextcloud.talk.models.json.conversations.RoomOverall - -class FakeApiService() : NcApiCoroutines { - override suspend fun getContactsWithSearchParam( - authorization: String?, - url: String?, - listOfShareTypes: List?, - options: Map? - ): AutocompleteOverall { - TODO("Not yet implemented") - } - - override suspend fun createRoom(authorization: String?, url: String?, options: Map?): RoomOverall { - TODO("Not yet implemented") - } -} diff --git a/app/src/test/java/com/nextcloud/talk/contacts/apiService/FakeItem.kt b/app/src/test/java/com/nextcloud/talk/contacts/apiService/FakeItem.kt index 95431275b..d419c2e7d 100644 --- a/app/src/test/java/com/nextcloud/talk/contacts/apiService/FakeItem.kt +++ b/app/src/test/java/com/nextcloud/talk/contacts/apiService/FakeItem.kt @@ -7,4 +7,38 @@ package com.nextcloud.talk.contacts.apiService -object FakeItem +import com.nextcloud.talk.models.json.autocomplete.AutocompleteOCS +import com.nextcloud.talk.models.json.autocomplete.AutocompleteOverall +import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser +import com.nextcloud.talk.models.json.generic.GenericMeta + +object FakeItem { + val contacts: List? = + listOf( + AutocompleteUser(id = "android", label = "Android", source = "users"), + AutocompleteUser(id = "android1", label = "Android 1", source = "users"), + AutocompleteUser(id = "android2", label = "Android 2", source = "users"), + AutocompleteUser(id = "Benny", label = "Benny J", source = "users"), + AutocompleteUser(id = "Benjamin", label = "Benjamin Schmidt", source = "users"), + AutocompleteUser(id = "Chris", label = "Christoph Schmidt", source = "users"), + AutocompleteUser(id = "Daniel", label = "Daniel H", source = "users"), + AutocompleteUser(id = "Dennis", label = "Dennis Richard", source = "users"), + AutocompleteUser(id = "Emma", label = "Emma Jackson", source = "users"), + AutocompleteUser(id = "Emily", label = "Emily Jackson", source = "users"), + AutocompleteUser(id = "Mario", label = "Mario Schmidt", source = "users"), + AutocompleteUser(id = "Maria", label = "Maria Schmidt", source = "users"), + AutocompleteUser(id = "Samsung", label = "Samsung A52", source = "users"), + AutocompleteUser(id = "Tom", label = "Tom Müller", source = "users"), + AutocompleteUser(id = "Tony", label = "Tony Baker", source = "users") + ) + val contactsOverall = AutocompleteOverall( + ocs = AutocompleteOCS( + meta = GenericMeta( + status = "ok", + statusCode = 200, + message = "OK" + ), + data = contacts + ) + ) +} diff --git a/app/src/test/java/com/nextcloud/talk/contacts/repository/FakeRepositoryError.kt b/app/src/test/java/com/nextcloud/talk/contacts/repository/FakeRepositoryError.kt index 6c488c4a2..1efa721ec 100644 --- a/app/src/test/java/com/nextcloud/talk/contacts/repository/FakeRepositoryError.kt +++ b/app/src/test/java/com/nextcloud/talk/contacts/repository/FakeRepositoryError.kt @@ -13,7 +13,7 @@ import com.nextcloud.talk.models.json.conversations.RoomOverall class FakeRepositoryError() : ContactsRepository { override suspend fun getContacts(searchQuery: String?, shareTypes: List): AutocompleteOverall { - TODO("Not yet implemented") + throw Exception("unknown error occurred") } override suspend fun createRoom( @@ -22,6 +22,10 @@ class FakeRepositoryError() : ContactsRepository { userId: String, conversationName: String? ): RoomOverall { - TODO("Not yet implemented") + throw Exception("unknown error occurred") + } + + override fun getImageUri(avatarId: String, requestBigSize: Boolean): String { + throw Exception("unknown error occurred") } } diff --git a/app/src/test/java/com/nextcloud/talk/contacts/repository/FakeRepositorySuccess.kt b/app/src/test/java/com/nextcloud/talk/contacts/repository/FakeRepositorySuccess.kt index 4cbf6453f..24bca99c3 100644 --- a/app/src/test/java/com/nextcloud/talk/contacts/repository/FakeRepositorySuccess.kt +++ b/app/src/test/java/com/nextcloud/talk/contacts/repository/FakeRepositorySuccess.kt @@ -8,12 +8,13 @@ package com.nextcloud.talk.contacts.repository import com.nextcloud.talk.contacts.ContactsRepository +import com.nextcloud.talk.contacts.apiService.FakeItem import com.nextcloud.talk.models.json.autocomplete.AutocompleteOverall import com.nextcloud.talk.models.json.conversations.RoomOverall class FakeRepositorySuccess() : ContactsRepository { override suspend fun getContacts(searchQuery: String?, shareTypes: List): AutocompleteOverall { - TODO("Not yet implemented") + return FakeItem.contactsOverall } override suspend fun createRoom( @@ -24,4 +25,8 @@ class FakeRepositorySuccess() : ContactsRepository { ): RoomOverall { TODO("Not yet implemented") } + + override fun getImageUri(avatarId: String, requestBigSize: Boolean): String { + TODO("Not yet implemented") + } } diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 5357f3465..b11953c8d 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -7,10 +7,10 @@ - + @@ -39,7 +39,10 @@ - + + + + @@ -156,6 +159,7 @@ + @@ -295,6 +299,14 @@ + + + + + + + + @@ -412,6 +424,20 @@ + + + + + + + + + + + + + +