From 2582476a54269ca4ac3fd7cdb1db945399c5533d Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Wed, 22 May 2024 16:09:12 +0200 Subject: [PATCH 01/12] Contacts Screen Signed-off-by: sowjanyakch --- .../talk/contacts/ContactsActivityCompose.kt | 2 + .../contacts/ContactsActivityViewModel.kt | 104 ++++++++++++ .../baseline_chat_bubble_outline_24.xml | 4 +- build.gradle | 4 +- gradle/verification-metadata.xml | 158 ++++++++++++++++-- 5 files changed, 249 insertions(+), 23 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityViewModel.kt 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 0746d7a61..fd4164525 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt @@ -327,6 +327,8 @@ fun ConversationCreationOptions(context: Context) { } } + + class CompanionClass { companion object { internal val TAG = ContactsActivityCompose::class.simpleName diff --git a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityViewModel.kt b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityViewModel.kt new file mode 100644 index 000000000..6c87c6608 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityViewModel.kt @@ -0,0 +1,104 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2024 Your Name + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +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 ContactsActivityViewModel @Inject constructor( + private val repository: ContactsRepository, + private val userManager: UserManager +) : 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) + val shareTypeList: List = shareTypes + + init { + getContactsFromSearchParams() + } + + fun updateSearchQuery(query: String) { + _searchQuery.value = query + } + + fun updateShareTypes(value: String) { + shareTypes.add(value) + } + + fun getContactsFromSearchParams() { + _contactsViewState.value = ContactsUiState.Loading + viewModelScope.launch { + try { + val contacts = repository.getContacts( + searchQuery.value, + shareTypeList + ) + val contactsList: List? = contacts.ocs!!.data + _contactsViewState.value = ContactsUiState.Success(contactsList) + } catch (exception: Exception) { + _contactsViewState.value = ContactsUiState.Error(exception.message ?: "") + } + } + } + + fun createRoom(roomType: String, sourceType: String, userId: String, conversationName: String?) { + viewModelScope.launch { + try { + val room = repository.createRoom( + roomType, + sourceType, + userId, + conversationName + ) + + val conversation: Conversation? = room.ocs?.data + _roomViewState.value = RoomUiState.Success(conversation) + } catch (exception: Exception) { + _roomViewState.value = RoomUiState.Error(exception.message ?: "") + } + } + } + + fun getImageUri(avatarId: String, requestBigSize: Boolean): String { + return ApiUtils.getUrlForAvatar( + _currentUser.baseUrl, + avatarId, + requestBigSize + ) + } +} + +sealed class ContactsUiState { + data object None : ContactsUiState() + data object Loading : ContactsUiState() + data class Success(val contacts: List?) : ContactsUiState() + data class Error(val message: String) : ContactsUiState() +} + +sealed class RoomUiState { + data object None : RoomUiState() + data class Success(val conversation: Conversation?) : RoomUiState() + data class Error(val message: String) : RoomUiState() +} diff --git a/app/src/main/res/drawable/baseline_chat_bubble_outline_24.xml b/app/src/main/res/drawable/baseline_chat_bubble_outline_24.xml index 50892e8fb..9b0454c0c 100644 --- a/app/src/main/res/drawable/baseline_chat_bubble_outline_24.xml +++ b/app/src/main/res/drawable/baseline_chat_bubble_outline_24.xml @@ -11,8 +11,8 @@ android:viewportHeight="24" android:viewportWidth="24" android:width="24dp"> - + - + diff --git a/build.gradle b/build.gradle index d2f3e8054..82654f5a9 100644 --- a/build.gradle +++ b/build.gradle @@ -12,11 +12,9 @@ buildscript { ext { kotlinVersion = '1.9.23' - hilt_version = '2.44' - kotlinVersion = '2.0.0' + hilt_version = '2.44' } - repositories { google() gradlePluginPortal() diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 05daccc8e..997eace8e 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -4,13 +4,13 @@ true true - - - - + + + + @@ -135,7 +135,6 @@ - @@ -147,6 +146,7 @@ + @@ -232,6 +232,7 @@ + @@ -326,6 +327,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -342,6 +387,14 @@ + + + + + + + + @@ -355,19 +408,10 @@ - - - - - - - - - - - - - + + + + @@ -376,6 +420,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4902,6 +5016,14 @@ + + + + + + + + From d3ff2e9ee90faaa2bd49d91e67f2a33bf7687233 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Wed, 10 Jul 2024 12:43:22 +0200 Subject: [PATCH 02/12] ViewModelModule.kt changes Signed-off-by: sowjanyakch --- .../contacts/ContactsActivityViewModel.kt | 104 ------------------ .../talk/dagger/modules/ViewModelModule.kt | 1 + 2 files changed, 1 insertion(+), 104 deletions(-) delete mode 100644 app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityViewModel.kt diff --git a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityViewModel.kt b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityViewModel.kt deleted file mode 100644 index 6c87c6608..000000000 --- a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityViewModel.kt +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Nextcloud Talk - Android Client - * - * SPDX-FileCopyrightText: 2024 Your Name - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -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 ContactsActivityViewModel @Inject constructor( - private val repository: ContactsRepository, - private val userManager: UserManager -) : 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) - val shareTypeList: List = shareTypes - - init { - getContactsFromSearchParams() - } - - fun updateSearchQuery(query: String) { - _searchQuery.value = query - } - - fun updateShareTypes(value: String) { - shareTypes.add(value) - } - - fun getContactsFromSearchParams() { - _contactsViewState.value = ContactsUiState.Loading - viewModelScope.launch { - try { - val contacts = repository.getContacts( - searchQuery.value, - shareTypeList - ) - val contactsList: List? = contacts.ocs!!.data - _contactsViewState.value = ContactsUiState.Success(contactsList) - } catch (exception: Exception) { - _contactsViewState.value = ContactsUiState.Error(exception.message ?: "") - } - } - } - - fun createRoom(roomType: String, sourceType: String, userId: String, conversationName: String?) { - viewModelScope.launch { - try { - val room = repository.createRoom( - roomType, - sourceType, - userId, - conversationName - ) - - val conversation: Conversation? = room.ocs?.data - _roomViewState.value = RoomUiState.Success(conversation) - } catch (exception: Exception) { - _roomViewState.value = RoomUiState.Error(exception.message ?: "") - } - } - } - - fun getImageUri(avatarId: String, requestBigSize: Boolean): String { - return ApiUtils.getUrlForAvatar( - _currentUser.baseUrl, - avatarId, - requestBigSize - ) - } -} - -sealed class ContactsUiState { - data object None : ContactsUiState() - data object Loading : ContactsUiState() - data class Success(val contacts: List?) : ContactsUiState() - data class Error(val message: String) : ContactsUiState() -} - -sealed class RoomUiState { - data object None : RoomUiState() - data class Success(val conversation: Conversation?) : RoomUiState() - data class Error(val message: String) : RoomUiState() -} diff --git a/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt b/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt index 511e6d7e2..0db93ac1c 100644 --- a/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt +++ b/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt @@ -12,6 +12,7 @@ import androidx.lifecycle.ViewModelProvider import com.nextcloud.talk.chat.viewmodels.ChatViewModel import com.nextcloud.talk.contacts.ContactsViewModel import com.nextcloud.talk.chat.viewmodels.MessageInputViewModel +import com.nextcloud.talk.contacts.ContactsViewModel import com.nextcloud.talk.conversation.viewmodel.ConversationViewModel import com.nextcloud.talk.conversation.viewmodel.RenameConversationViewModel import com.nextcloud.talk.conversationinfo.viewmodel.ConversationInfoViewModel From 5d73b65a3194f2670d787fdfcd3246d9afc74283 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Tue, 16 Jul 2024 22:21:33 +0200 Subject: [PATCH 03/12] test dependencies Signed-off-by: sowjanyakch --- app/build.gradle | 5 +++ .../talk/contacts/ContactsActivityCompose.kt | 31 ++++++++-------- .../nextcloud/talk/contacts/ImageRequest.kt | 24 +++++++++++++ .../nextcloud/talk/contacts/MyApplication.kt | 35 +++++++++++++++++++ .../talk/contacts/SearchComponent.kt | 14 ++++---- gradle/verification-metadata.xml | 2 +- 6 files changed, 90 insertions(+), 21 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/talk/contacts/ImageRequest.kt create mode 100644 app/src/main/java/com/nextcloud/talk/contacts/MyApplication.kt diff --git a/app/build.gradle b/app/build.gradle index e7678fb55..0a8b8285f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -333,6 +333,11 @@ dependencies { implementation "com.google.dagger:hilt-android:$hilt_version" kapt "com.google.dagger:hilt-android-compiler:$hilt_version" + + implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.3") + testImplementation("junit:junit:4.13.2") + androidTestImplementation(platform("androidx.compose:compose-bom:2024.06.00")) + androidTestImplementation("androidx.compose.ui:ui-test-junit4") } 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 fd4164525..0caa1f65b 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt @@ -52,6 +52,7 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -61,13 +62,12 @@ import androidx.compose.ui.unit.sp import androidx.lifecycle.ViewModelProvider import autodagger.AutoInjector import coil.compose.AsyncImage -import coil.request.ImageRequest -import coil.transform.CircleCropTransformation import com.nextcloud.talk.R import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser import com.nextcloud.talk.openconversations.ListOpenConversationsActivity +import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.bundle.BundleKeys import javax.inject.Inject @@ -78,6 +78,9 @@ class ContactsActivityCompose : ComponentActivity() { lateinit var viewModelFactory: ViewModelProvider.Factory private lateinit var contactsViewModel: ContactsViewModel + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + @SuppressLint("UnrememberedMutableState") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -85,7 +88,9 @@ class ContactsActivityCompose : ComponentActivity() { contactsViewModel = ViewModelProvider(this, viewModelFactory)[ContactsViewModel::class.java] setContent { - MaterialTheme { + MaterialTheme( + colorScheme = viewThemeUtils.getColorScheme(this) + ) { val context = LocalContext.current Scaffold( topBar = { @@ -205,15 +210,10 @@ fun ContactItemRow(contact: AutocompleteUser, contactsViewModel: ContactsViewMod verticalAlignment = Alignment.CenterVertically ) { val imageUri = contact.id?.let { contactsViewModel.getImageUri(it, true) } - val imageRequest = ImageRequest.Builder(context) - .data(imageUri) - .transformations(CircleCropTransformation()) - .error(R.drawable.account_circle_96dp) - .placeholder(R.drawable.account_circle_96dp) - .build() - + val errorPlaceholderImage: Int = R.drawable.account_circle_96dp + val loadedImage = loadImage(imageUri, context, errorPlaceholderImage) AsyncImage( - model = imageRequest, + model = loadedImage, contentDescription = stringResource(R.string.user_avatar), modifier = Modifier.size(width = 45.dp, height = 45.dp) ) @@ -288,7 +288,8 @@ fun ConversationCreationOptions(context: Context) { .height(40.dp) .padding(8.dp), painter = painterResource(R.drawable.baseline_chat_bubble_outline_24), - contentDescription = stringResource(R.string.new_conversation_creation_icon) + contentDescription = stringResource(R.string.new_conversation_creation_icon), + colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSurface) ) Text( modifier = Modifier @@ -296,7 +297,8 @@ fun ConversationCreationOptions(context: Context) { .wrapContentHeight(), text = stringResource(R.string.nc_create_new_conversation), maxLines = 1, - fontSize = 16.sp + fontSize = 16.sp, + color = MaterialTheme.colorScheme.onSurface ) } Row( @@ -314,7 +316,8 @@ fun ConversationCreationOptions(context: Context) { .height(40.dp) .padding(8.dp), painter = painterResource(R.drawable.baseline_format_list_bulleted_24), - contentDescription = stringResource(R.string.join_open_conversations_icon) + contentDescription = stringResource(R.string.join_open_conversations_icon), + colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSurface) ) Text( modifier = Modifier diff --git a/app/src/main/java/com/nextcloud/talk/contacts/ImageRequest.kt b/app/src/main/java/com/nextcloud/talk/contacts/ImageRequest.kt new file mode 100644 index 000000000..c91061308 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/contacts/ImageRequest.kt @@ -0,0 +1,24 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2024 Sowjanya Kota + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.contacts + +import android.content.Context +import androidx.compose.runtime.Composable +import coil.request.ImageRequest +import coil.transform.CircleCropTransformation + +@Composable +fun loadImage(imageUri: String?, context: Context, errorPlaceholderImage: Int): ImageRequest { + val imageRequest = ImageRequest.Builder(context) + .data(imageUri) + .transformations(CircleCropTransformation()) + .error(errorPlaceholderImage) + .placeholder(errorPlaceholderImage) + .build() + return imageRequest +} diff --git a/app/src/main/java/com/nextcloud/talk/contacts/MyApplication.kt b/app/src/main/java/com/nextcloud/talk/contacts/MyApplication.kt new file mode 100644 index 000000000..c25bbe120 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/contacts/MyApplication.kt @@ -0,0 +1,35 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2024 Your Name + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.contacts + +import android.app.Application +import coil.ImageLoader +import coil.ImageLoaderFactory +import coil.disk.DiskCache +import coil.memory.MemoryCache +import coil.util.DebugLogger + +class MyApplication : Application(), ImageLoaderFactory { + override fun newImageLoader(): ImageLoader { + val imageLoader = ImageLoader.Builder(this) + .memoryCache { + MemoryCache.Builder(this) + .maxSizePercent(0.1) + .build() + } + .diskCache { + DiskCache.Builder() + .maxSizePercent(0.02) + .directory(cacheDir) + .build() + } + .logger(DebugLogger()) + .build() + return imageLoader + } +} diff --git a/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt b/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt index 7adaef8bf..d5c61fd1e 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt @@ -17,6 +17,7 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Close import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextField @@ -38,23 +39,24 @@ fun DisplaySearch(text: String, onTextChange: (String) -> Unit, contactsViewMode modifier = Modifier .fillMaxWidth() .height(60.dp) - .background(Color.White) + ) { val keyboardController = LocalSoftwareKeyboardController.current TextField( modifier = Modifier - .fillMaxWidth(), + .fillMaxWidth() + .background(MaterialTheme.colorScheme.surface), value = text, onValueChange = { onTextChange(it) }, placeholder = { Text( text = stringResource(R.string.nc_search), - color = Color.DarkGray + color = MaterialTheme.colorScheme.onSurfaceVariant ) }, textStyle = TextStyle( - color = Color.Black, + color = MaterialTheme.colorScheme.onSurface, fontSize = 16.sp ), singleLine = true, @@ -68,7 +70,7 @@ fun DisplaySearch(text: String, onTextChange: (String) -> Unit, contactsViewMode Icon( imageVector = Icons.AutoMirrored.Default.ArrowBack, contentDescription = stringResource(R.string.back_button), - tint = Color.Black + tint = MaterialTheme.colorScheme.onSurface ) } }, @@ -83,7 +85,7 @@ fun DisplaySearch(text: String, onTextChange: (String) -> Unit, contactsViewMode Icon( imageVector = Icons.Default.Close, contentDescription = stringResource(R.string.close_icon), - tint = Color.Black + tint = MaterialTheme.colorScheme.onSurface ) } } diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 997eace8e..5357f3465 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -5982,7 +5982,7 @@ - + From acbda6f887a602a003a95af87b004156a7bd5a1e Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Wed, 17 Jul 2024 22:00:16 +0200 Subject: [PATCH 04/12] Create fake data for unit tests Signed-off-by: sowjanyakch --- .../talk/contacts/ContactsActivityCompose.kt | 24 ++++++-------- .../talk/contacts/SearchComponent.kt | 32 +++++++------------ .../contacts/apiService/FakeApiService.kt | 27 ++++++++++++++++ .../talk/contacts/apiService/FakeItem.kt | 11 +++++++ .../repository/FakeRepositoryError.kt | 27 ++++++++++++++++ .../repository/FakeRepositorySuccess.kt | 27 ++++++++++++++++ 6 files changed, 114 insertions(+), 34 deletions(-) create mode 100644 app/src/test/java/com/nextcloud/talk/contacts/apiService/FakeApiService.kt create mode 100644 app/src/test/java/com/nextcloud/talk/contacts/apiService/FakeItem.kt create mode 100644 app/src/test/java/com/nextcloud/talk/contacts/repository/FakeRepositoryError.kt create mode 100644 app/src/test/java/com/nextcloud/talk/contacts/repository/FakeRepositorySuccess.kt 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 0caa1f65b..e0d5d0a43 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt @@ -13,7 +13,6 @@ import android.content.Context import android.content.Intent import android.os.Bundle import android.util.Log -import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image @@ -52,7 +51,6 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -63,24 +61,21 @@ import androidx.lifecycle.ViewModelProvider import autodagger.AutoInjector import coil.compose.AsyncImage import com.nextcloud.talk.R +import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser import com.nextcloud.talk.openconversations.ListOpenConversationsActivity -import com.nextcloud.talk.ui.theme.ViewThemeUtils import com.nextcloud.talk.utils.bundle.BundleKeys import javax.inject.Inject @AutoInjector(NextcloudTalkApplication::class) -class ContactsActivityCompose : ComponentActivity() { +class ContactsActivityCompose : BaseActivity() { @Inject lateinit var viewModelFactory: ViewModelProvider.Factory private lateinit var contactsViewModel: ContactsViewModel - @Inject - lateinit var viewThemeUtils: ViewThemeUtils - @SuppressLint("UnrememberedMutableState") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -88,8 +83,9 @@ class ContactsActivityCompose : ComponentActivity() { contactsViewModel = ViewModelProvider(this, viewModelFactory)[ContactsViewModel::class.java] setContent { + val colorScheme = viewThemeUtils.getColorScheme(this) MaterialTheme( - colorScheme = viewThemeUtils.getColorScheme(this) + colorScheme = colorScheme ) { val context = LocalContext.current Scaffold( @@ -288,8 +284,8 @@ fun ConversationCreationOptions(context: Context) { .height(40.dp) .padding(8.dp), painter = painterResource(R.drawable.baseline_chat_bubble_outline_24), - contentDescription = stringResource(R.string.new_conversation_creation_icon), - colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSurface) + contentDescription = stringResource(R.string.new_conversation_creation_icon) + // colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSurface) ) Text( modifier = Modifier @@ -297,8 +293,8 @@ fun ConversationCreationOptions(context: Context) { .wrapContentHeight(), text = stringResource(R.string.nc_create_new_conversation), maxLines = 1, - fontSize = 16.sp, - color = MaterialTheme.colorScheme.onSurface + fontSize = 16.sp + // color = MaterialTheme.colorScheme.onSurface ) } Row( @@ -316,8 +312,8 @@ fun ConversationCreationOptions(context: Context) { .height(40.dp) .padding(8.dp), painter = painterResource(R.drawable.baseline_format_list_bulleted_24), - contentDescription = stringResource(R.string.join_open_conversations_icon), - colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSurface) + contentDescription = stringResource(R.string.join_open_conversations_icon) + // colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSurface) ) Text( modifier = Modifier diff --git a/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt b/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt index d5c61fd1e..f8f2f87c3 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt @@ -7,7 +7,6 @@ package com.nextcloud.talk.contacts -import androidx.compose.foundation.background import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.text.KeyboardActions @@ -17,14 +16,11 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Close import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextField -import androidx.compose.material3.TextFieldDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle @@ -44,19 +40,19 @@ fun DisplaySearch(text: String, onTextChange: (String) -> Unit, contactsViewMode val keyboardController = LocalSoftwareKeyboardController.current TextField( modifier = Modifier - .fillMaxWidth() - .background(MaterialTheme.colorScheme.surface), + .fillMaxWidth(), + // .background(MaterialTheme.colorScheme.surface), value = text, onValueChange = { onTextChange(it) }, placeholder = { Text( - text = stringResource(R.string.nc_search), - color = MaterialTheme.colorScheme.onSurfaceVariant + text = stringResource(R.string.nc_search) + // color = MaterialTheme.colorScheme.onSurfaceVariant ) }, textStyle = TextStyle( - color = MaterialTheme.colorScheme.onSurface, + // color = MaterialTheme.colorScheme.onSurface, fontSize = 16.sp ), singleLine = true, @@ -69,8 +65,8 @@ fun DisplaySearch(text: String, onTextChange: (String) -> Unit, contactsViewMode ) { Icon( imageVector = Icons.AutoMirrored.Default.ArrowBack, - contentDescription = stringResource(R.string.back_button), - tint = MaterialTheme.colorScheme.onSurface + contentDescription = stringResource(R.string.back_button) + // tint = MaterialTheme.colorScheme.onSurface ) } }, @@ -85,7 +81,7 @@ fun DisplaySearch(text: String, onTextChange: (String) -> Unit, contactsViewMode Icon( imageVector = Icons.Default.Close, contentDescription = stringResource(R.string.close_icon), - tint = MaterialTheme.colorScheme.onSurface + //tint = MaterialTheme.colorScheme.onSurface ) } } @@ -104,14 +100,10 @@ fun DisplaySearch(text: String, onTextChange: (String) -> Unit, contactsViewMode } } ), - maxLines = 1, - colors = TextFieldDefaults.colors( - focusedContainerColor = Color.White, - unfocusedContainerColor = Color.White, - disabledContainerColor = Color.White, - focusedTextColor = Color.Black, - cursorColor = Color.Black - ) + maxLines = 1 + // colors = TextFieldDefaults.colors( + // cursorColor = Color.Blue + // ) ) } } 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 new file mode 100644 index 000000000..37ffad6fe --- /dev/null +++ b/app/src/test/java/com/nextcloud/talk/contacts/apiService/FakeApiService.kt @@ -0,0 +1,27 @@ +/* + * 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 new file mode 100644 index 000000000..bce9c4d6f --- /dev/null +++ b/app/src/test/java/com/nextcloud/talk/contacts/apiService/FakeItem.kt @@ -0,0 +1,11 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2024 Your Name + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.contacts.apiService + +object FakeItem { +} 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 new file mode 100644 index 000000000..6c488c4a2 --- /dev/null +++ b/app/src/test/java/com/nextcloud/talk/contacts/repository/FakeRepositoryError.kt @@ -0,0 +1,27 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2024 Your Name + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.contacts.repository + +import com.nextcloud.talk.contacts.ContactsRepository +import com.nextcloud.talk.models.json.autocomplete.AutocompleteOverall +import com.nextcloud.talk.models.json.conversations.RoomOverall + +class FakeRepositoryError() : ContactsRepository { + override suspend fun getContacts(searchQuery: String?, shareTypes: List): AutocompleteOverall { + TODO("Not yet implemented") + } + + override suspend fun createRoom( + roomType: String, + sourceType: String, + userId: String, + conversationName: String? + ): RoomOverall { + TODO("Not yet implemented") + } +} 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 new file mode 100644 index 000000000..4cbf6453f --- /dev/null +++ b/app/src/test/java/com/nextcloud/talk/contacts/repository/FakeRepositorySuccess.kt @@ -0,0 +1,27 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2024 Your Name + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.contacts.repository + +import com.nextcloud.talk.contacts.ContactsRepository +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") + } + + override suspend fun createRoom( + roomType: String, + sourceType: String, + userId: String, + conversationName: String? + ): RoomOverall { + TODO("Not yet implemented") + } +} From 9526825da7fb9d94e510781bcb11c019b68dd0ae Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Thu, 18 Jul 2024 21:58:28 +0200 Subject: [PATCH 05/12] Refactor - use Icons Signed-off-by: sowjanyakch --- .../talk/contacts/ContactsActivityCompose.kt | 22 +++-- .../talk/contacts/SearchComponent.kt | 86 ++++++++----------- .../talk/contacts/apiService/FakeItem.kt | 3 +- 3 files changed, 47 insertions(+), 64 deletions(-) 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 e0d5d0a43..a5b111952 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt @@ -15,7 +15,6 @@ import android.os.Bundle import android.util.Log import androidx.activity.compose.setContent import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -34,6 +33,7 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.automirrored.filled.List import androidx.compose.material.icons.filled.Search import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api @@ -81,9 +81,9 @@ class ContactsActivityCompose : BaseActivity() { super.onCreate(savedInstanceState) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) contactsViewModel = ViewModelProvider(this, viewModelFactory)[ContactsViewModel::class.java] - setContent { val colorScheme = viewThemeUtils.getColorScheme(this) + val uiState = contactsViewModel.contactsViewState.collectAsState() MaterialTheme( colorScheme = colorScheme ) { @@ -97,7 +97,6 @@ class ContactsActivityCompose : BaseActivity() { ) }, content = { - val uiState = contactsViewModel.contactsViewState.collectAsState() Column(Modifier.padding(it)) { ConversationCreationOptions(context = context) ContactsList( @@ -242,8 +241,10 @@ fun ContactItemRow(contact: AutocompleteUser, contactsViewModel: ContactsViewMod fun AppBar(title: String, context: Context, contactsViewModel: ContactsViewModel) { val searchQuery by contactsViewModel.searchQuery.collectAsState() val searchState = contactsViewModel.searchState.collectAsState() + TopAppBar( title = { Text(text = title) }, + navigationIcon = { IconButton(onClick = { (context as? Activity)?.finish() @@ -278,14 +279,13 @@ fun ConversationCreationOptions(context: Context) { modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 8.dp), verticalAlignment = Alignment.CenterVertically ) { - Image( + Icon( + painter = painterResource(id = R.drawable.baseline_chat_bubble_outline_24), modifier = Modifier .width(40.dp) .height(40.dp) .padding(8.dp), - painter = painterResource(R.drawable.baseline_chat_bubble_outline_24), - contentDescription = stringResource(R.string.new_conversation_creation_icon) - // colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSurface) + contentDescription = null ) Text( modifier = Modifier @@ -294,7 +294,6 @@ fun ConversationCreationOptions(context: Context) { text = stringResource(R.string.nc_create_new_conversation), maxLines = 1, fontSize = 16.sp - // color = MaterialTheme.colorScheme.onSurface ) } Row( @@ -306,14 +305,13 @@ fun ConversationCreationOptions(context: Context) { }, verticalAlignment = Alignment.CenterVertically ) { - Image( + Icon( + Icons.AutoMirrored.Filled.List, modifier = Modifier .width(40.dp) .height(40.dp) .padding(8.dp), - painter = painterResource(R.drawable.baseline_format_list_bulleted_24), - contentDescription = stringResource(R.string.join_open_conversations_icon) - // colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSurface) + contentDescription = null ) Text( modifier = Modifier diff --git a/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt b/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt index f8f2f87c3..d8daf8ed4 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt @@ -16,7 +16,6 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Close import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.runtime.Composable @@ -31,45 +30,36 @@ import com.nextcloud.talk.R @Composable fun DisplaySearch(text: String, onTextChange: (String) -> Unit, contactsViewModel: ContactsViewModel) { - Surface( + val keyboardController = LocalSoftwareKeyboardController.current + TextField( modifier = Modifier .fillMaxWidth() - .height(60.dp) + .height(60.dp), + value = text, + onValueChange = { onTextChange(it) }, + placeholder = { + Text( + text = stringResource(R.string.nc_search) + ) + }, - ) { - val keyboardController = LocalSoftwareKeyboardController.current - TextField( - modifier = Modifier - .fillMaxWidth(), - // .background(MaterialTheme.colorScheme.surface), - value = text, - onValueChange = { onTextChange(it) }, - placeholder = { - Text( - text = stringResource(R.string.nc_search) - // color = MaterialTheme.colorScheme.onSurfaceVariant - ) - }, - - textStyle = TextStyle( - // color = MaterialTheme.colorScheme.onSurface, - fontSize = 16.sp - ), - singleLine = true, - leadingIcon = { - IconButton( - onClick = { - onTextChange("") - contactsViewModel.updateSearchState(false) - } - ) { - Icon( - imageVector = Icons.AutoMirrored.Default.ArrowBack, - contentDescription = stringResource(R.string.back_button) - // tint = MaterialTheme.colorScheme.onSurface - ) + textStyle = TextStyle( + fontSize = 16.sp + ), + singleLine = true, + leadingIcon = { + IconButton( + onClick = { + onTextChange("") + contactsViewModel.updateSearchState(false) } - }, + ) { + Icon( + imageVector = Icons.AutoMirrored.Default.ArrowBack, + contentDescription = stringResource(R.string.back_button) + ) + } + }, trailingIcon = { if (text.isNotEmpty()) { @@ -91,19 +81,15 @@ fun DisplaySearch(text: String, onTextChange: (String) -> Unit, contactsViewMode imeAction = ImeAction.Search ), - keyboardActions = KeyboardActions( - onSearch = { - if (text.trim().isNotEmpty()) { - keyboardController?.hide() - } else { - return@KeyboardActions - } + keyboardActions = KeyboardActions( + onSearch = { + if (text.trim().isNotEmpty()) { + keyboardController?.hide() + } else { + return@KeyboardActions } - ), - maxLines = 1 - // colors = TextFieldDefaults.colors( - // cursorColor = Color.Blue - // ) - ) - } + } + ), + maxLines = 1 + ) } 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 bce9c4d6f..95431275b 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,5 +7,4 @@ package com.nextcloud.talk.contacts.apiService -object FakeItem { -} +object FakeItem From 62b2ecd338e2cc81d712203e3b52f3a10ca7b131 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Mon, 22 Jul 2024 21:04:42 +0200 Subject: [PATCH 06/12] 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 @@ + + + + + + + + + + + + + + From 8d52a6fcc9cf54faa05b557aecffb9c5b3e8c294 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Tue, 23 Jul 2024 16:36:42 +0200 Subject: [PATCH 07/12] add error test case for contacts fetch Signed-off-by: sowjanyakch --- .../talk/contacts/ContactsActivityCompose.kt | 2 -- .../talk/contacts/SearchComponent.kt | 31 +++++++++---------- .../talk/dagger/modules/ViewModelModule.kt | 1 - .../talk/contacts/ContactsViewModelTest.kt | 11 ++++++- build.gradle | 2 +- gradle/verification-metadata.xml | 2 +- 6 files changed, 27 insertions(+), 22 deletions(-) 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 582cdf929..75fc8c1bd 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt @@ -325,8 +325,6 @@ fun ConversationCreationOptions(context: Context) { } } - - class CompanionClass { companion object { internal val TAG = ContactsActivityCompose::class.simpleName diff --git a/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt b/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt index d8daf8ed4..f7ba7d61b 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt @@ -61,25 +61,24 @@ fun DisplaySearch(text: String, onTextChange: (String) -> Unit, contactsViewMode } }, - trailingIcon = { - if (text.isNotEmpty()) { - IconButton( - onClick = { - onTextChange("") - } - ) { - Icon( - imageVector = Icons.Default.Close, - contentDescription = stringResource(R.string.close_icon), - //tint = MaterialTheme.colorScheme.onSurface - ) + trailingIcon = { + if (text.isNotEmpty()) { + IconButton( + onClick = { + onTextChange("") } + ) { + Icon( + imageVector = Icons.Default.Close, + contentDescription = stringResource(R.string.close_icon) + ) } - }, + } + }, - keyboardOptions = KeyboardOptions( - imeAction = ImeAction.Search - ), + keyboardOptions = KeyboardOptions( + imeAction = ImeAction.Search + ), keyboardActions = KeyboardActions( onSearch = { diff --git a/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt b/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt index 0db93ac1c..511e6d7e2 100644 --- a/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt +++ b/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt @@ -12,7 +12,6 @@ import androidx.lifecycle.ViewModelProvider import com.nextcloud.talk.chat.viewmodels.ChatViewModel import com.nextcloud.talk.contacts.ContactsViewModel import com.nextcloud.talk.chat.viewmodels.MessageInputViewModel -import com.nextcloud.talk.contacts.ContactsViewModel import com.nextcloud.talk.conversation.viewmodel.ConversationViewModel import com.nextcloud.talk.conversation.viewmodel.RenameConversationViewModel import com.nextcloud.talk.conversationinfo.viewmodel.ConversationInfoViewModel diff --git a/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt b/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt index feabd9230..632f41182 100644 --- a/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt +++ b/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt @@ -8,6 +8,7 @@ package com.nextcloud.talk.contacts import com.nextcloud.talk.contacts.apiService.FakeItem +import com.nextcloud.talk.contacts.repository.FakeRepositoryError import com.nextcloud.talk.contacts.repository.FakeRepositorySuccess import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -38,16 +39,24 @@ class ContactsViewModelTest { } @Before - fun setUp() { + fun setUp() { viewModel = ContactsViewModel(repository) } @Test fun `fetch contacts`() = runTest { + viewModel = ContactsViewModel(repository) viewModel.getContactsFromSearchParams() assert(viewModel.contactsViewState.value is ContactsUiState.Success) val successState = viewModel.contactsViewState.value as ContactsUiState.Success assert(successState.contacts == FakeItem.contacts) } + + @Test + fun `fetch contacts with error`() = + runTest { + viewModel = ContactsViewModel(FakeRepositoryError()) + assert(viewModel.contactsViewState.value is ContactsUiState.Error) + } } diff --git a/build.gradle b/build.gradle index 82654f5a9..6a0ab2789 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ buildscript { ext { - kotlinVersion = '1.9.23' + kotlinVersion = '2.0.0' hilt_version = '2.44' } diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index b11953c8d..1fa1435c6 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -138,6 +138,7 @@ + @@ -149,7 +150,6 @@ - From d656a93e8aa293f739deda3c75c74a18b2fff23c Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Thu, 25 Jul 2024 00:06:11 +0200 Subject: [PATCH 08/12] add test cases for create room Signed-off-by: sowjanyakch --- .../talk/contacts/ContactsViewModelTest.kt | 48 ++++++++++++++++++- .../talk/contacts/apiService/FakeItem.kt | 14 ++++++ .../repository/FakeRepositorySuccess.kt | 4 +- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt b/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt index 632f41182..f4ae66631 100644 --- a/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt +++ b/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt @@ -1,7 +1,7 @@ /* * Nextcloud Talk - Android Client * - * SPDX-FileCopyrightText: 2024 Your Name + * SPDX-FileCopyrightText: 2024 Sowjanya Kota * SPDX-License-Identifier: GPL-3.0-or-later */ @@ -59,4 +59,50 @@ class ContactsViewModelTest { viewModel = ContactsViewModel(FakeRepositoryError()) assert(viewModel.contactsViewState.value is ContactsUiState.Error) } + + @Test + fun `update search query`() { + viewModel.updateSearchQuery("Ma") + assert(viewModel.searchQuery.value == "Ma") + } + + @Test + fun `initial search query is empty string`() { + viewModel.updateSearchQuery("") + assert(viewModel.searchQuery.value == "") + } + + @Test + fun `initial shareType is User`() { + assert(viewModel.shareTypeList.contains(ShareType.User.shareType)) + } + + @Test + fun `update shareTypes`() { + viewModel.updateShareTypes(ShareType.Group.shareType) + assert(viewModel.shareTypeList.contains(ShareType.Group.shareType)) + } + + @Test + fun `initial room state is none`() = + runTest { + assert(viewModel.roomViewState.value is RoomUiState.None) + } + + @Test + fun `test success room state`() = + runTest { + viewModel.createRoom("1", "users", "s@gmail.com", null) + assert(viewModel.roomViewState.value is RoomUiState.Success) + val successState = viewModel.roomViewState.value as RoomUiState.Success + assert(successState.conversation == FakeItem.roomOverall.ocs!!.data) + } + + @Test + fun `test failure room state`() = + runTest { + viewModel = ContactsViewModel(FakeRepositoryError()) + viewModel.createRoom("1", "users", "s@gmail.com", null) + assert(viewModel.roomViewState.value is RoomUiState.Error) + } } 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 d419c2e7d..146ec8628 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 @@ -10,7 +10,11 @@ package com.nextcloud.talk.contacts.apiService 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.conversations.Conversation +import com.nextcloud.talk.models.json.conversations.RoomOCS +import com.nextcloud.talk.models.json.conversations.RoomOverall import com.nextcloud.talk.models.json.generic.GenericMeta +import org.mockito.Mockito.mock object FakeItem { val contacts: List? = @@ -41,4 +45,14 @@ object FakeItem { data = contacts ) ) + val roomOverall: RoomOverall = RoomOverall( + ocs = RoomOCS( + meta = GenericMeta( + status = "ok", + statusCode = 200, + message = "OK" + ), + data = mock(Conversation::class.java) + ) + ) } 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 24bca99c3..b5164c2c8 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 @@ -23,10 +23,10 @@ class FakeRepositorySuccess() : ContactsRepository { userId: String, conversationName: String? ): RoomOverall { - TODO("Not yet implemented") + return FakeItem.roomOverall } override fun getImageUri(avatarId: String, requestBigSize: Boolean): String { - TODO("Not yet implemented") + return "https://mydomain.com/index.php/avatar/$avatarId/512" } } From a51e3b98ad2f0ea80c9349ffb842eb63a577c175 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Thu, 25 Jul 2024 17:54:19 +0200 Subject: [PATCH 09/12] Image uri test cases Signed-off-by: sowjanyakch --- .../talk/contacts/ContactsViewModelTest.kt | 22 +++++++++++++++++-- .../repository/FakeRepositoryError.kt | 6 ++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt b/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt index f4ae66631..4d92bb480 100644 --- a/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt +++ b/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt @@ -58,16 +58,18 @@ class ContactsViewModelTest { runTest { viewModel = ContactsViewModel(FakeRepositoryError()) assert(viewModel.contactsViewState.value is ContactsUiState.Error) + val errorState = viewModel.contactsViewState.value as ContactsUiState.Error + assert(errorState.message == "unable to fetch contacts") } @Test - fun `update search query`() { + fun `update search query`() { viewModel.updateSearchQuery("Ma") assert(viewModel.searchQuery.value == "Ma") } @Test - fun `initial search query is empty string`() { + fun `initial search query is empty string`() { viewModel.updateSearchQuery("") assert(viewModel.searchQuery.value == "") } @@ -104,5 +106,21 @@ class ContactsViewModelTest { viewModel = ContactsViewModel(FakeRepositoryError()) viewModel.createRoom("1", "users", "s@gmail.com", null) assert(viewModel.roomViewState.value is RoomUiState.Error) + val errorState = viewModel.roomViewState.value as RoomUiState.Error + assert(errorState.message == "unable to create room") } + + @Test + fun `test image uri`() { + val expectedImageUri = "https://mydomain.com/index.php/avatar/vidya/512" + val imageUri = viewModel.getImageUri("vidya", false) + assert(imageUri == expectedImageUri) + } + + @Test + fun `test error image uri`() { + val expectedImageUri = "https://mydoman.com/index.php/avatar/vidya/512" + val imageUri = viewModel.getImageUri("vidya", false) + assert(imageUri != expectedImageUri) + } } 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 1efa721ec..ac9aeec26 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 { - throw Exception("unknown error occurred") + throw Exception("unable to fetch contacts") } override suspend fun createRoom( @@ -22,10 +22,10 @@ class FakeRepositoryError() : ContactsRepository { userId: String, conversationName: String? ): RoomOverall { - throw Exception("unknown error occurred") + throw Exception("unable to create room") } override fun getImageUri(avatarId: String, requestBigSize: Boolean): String { - throw Exception("unknown error occurred") + return "https://mydoman.com/index.php/avatar/$avatarId/512" } } From 77a9ae601f0439dd7a4379491c4cfaf4e41ec596 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Thu, 25 Jul 2024 17:57:22 +0200 Subject: [PATCH 10/12] add signature Signed-off-by: sowjanyakch --- .../java/com/nextcloud/talk/contacts/apiService/FakeItem.kt | 2 +- .../nextcloud/talk/contacts/repository/FakeRepositoryError.kt | 2 +- .../nextcloud/talk/contacts/repository/FakeRepositorySuccess.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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 146ec8628..99539fa64 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 @@ -1,7 +1,7 @@ /* * Nextcloud Talk - Android Client * - * SPDX-FileCopyrightText: 2024 Your Name + * SPDX-FileCopyrightText: 2024 Sowjanya Kota * SPDX-License-Identifier: GPL-3.0-or-later */ 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 ac9aeec26..40554eda8 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 @@ -1,7 +1,7 @@ /* * Nextcloud Talk - Android Client * - * SPDX-FileCopyrightText: 2024 Your Name + * SPDX-FileCopyrightText: 2024 Sowjanya Kota * SPDX-License-Identifier: GPL-3.0-or-later */ 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 b5164c2c8..fd16b5f54 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 @@ -1,7 +1,7 @@ /* * Nextcloud Talk - Android Client * - * SPDX-FileCopyrightText: 2024 Your Name + * SPDX-FileCopyrightText: 2024 Sowjanya Kota * SPDX-License-Identifier: GPL-3.0-or-later */ From c6fb2ef6e1d5fba55fcec7ea60623fb13508ef4d Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Thu, 25 Jul 2024 19:27:52 +0200 Subject: [PATCH 11/12] refactoring Signed-off-by: sowjanyakch --- .../java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt | 2 +- .../java/com/nextcloud/talk/contacts/apiService/FakeItem.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt b/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt index 4d92bb480..7bb905b43 100644 --- a/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt +++ b/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt @@ -54,7 +54,7 @@ class ContactsViewModelTest { } @Test - fun `fetch contacts with error`() = + fun `test error contacts state`() = runTest { viewModel = ContactsViewModel(FakeRepositoryError()) assert(viewModel.contactsViewState.value is ContactsUiState.Error) 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 99539fa64..acfcbfe30 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 @@ -17,7 +17,7 @@ import com.nextcloud.talk.models.json.generic.GenericMeta import org.mockito.Mockito.mock object FakeItem { - val contacts: List? = + val contacts: List = listOf( AutocompleteUser(id = "android", label = "Android", source = "users"), AutocompleteUser(id = "android1", label = "Android 1", source = "users"), From 4508cbb0aa234307aa4954f5d57f78ac844e64e1 Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Thu, 25 Jul 2024 19:46:47 +0200 Subject: [PATCH 12/12] work on codacy warnings Signed-off-by: sowjanyakch --- .../contacts/{MyApplication.kt => ContactsApplication.kt} | 7 ++++--- app/src/main/java/com/nextcloud/talk/utils/ContactUtils.kt | 2 ++ .../talk/contacts/repository/FakeRepositoryError.kt | 2 +- .../talk/contacts/repository/FakeRepositorySuccess.kt | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) rename app/src/main/java/com/nextcloud/talk/contacts/{MyApplication.kt => ContactsApplication.kt} (75%) diff --git a/app/src/main/java/com/nextcloud/talk/contacts/MyApplication.kt b/app/src/main/java/com/nextcloud/talk/contacts/ContactsApplication.kt similarity index 75% rename from app/src/main/java/com/nextcloud/talk/contacts/MyApplication.kt rename to app/src/main/java/com/nextcloud/talk/contacts/ContactsApplication.kt index c25bbe120..dbbfe4d3c 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/MyApplication.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsApplication.kt @@ -13,18 +13,19 @@ import coil.ImageLoaderFactory import coil.disk.DiskCache import coil.memory.MemoryCache import coil.util.DebugLogger +import com.nextcloud.talk.utils.ContactUtils -class MyApplication : Application(), ImageLoaderFactory { +class ContactsApplication : Application(), ImageLoaderFactory { override fun newImageLoader(): ImageLoader { val imageLoader = ImageLoader.Builder(this) .memoryCache { MemoryCache.Builder(this) - .maxSizePercent(0.1) + .maxSizePercent(ContactUtils.CACHE_MEMORY_SIZE_PERCENTAGE) .build() } .diskCache { DiskCache.Builder() - .maxSizePercent(0.02) + .maxSizePercent(ContactUtils.CACHE_DISK_SIZE_PERCENTAGE) .directory(cacheDir) .build() } diff --git a/app/src/main/java/com/nextcloud/talk/utils/ContactUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/ContactUtils.kt index cf8434993..74f1f24f5 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ContactUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/ContactUtils.kt @@ -12,6 +12,8 @@ import android.provider.ContactsContract object ContactUtils { const val MAX_CONTACT_LIMIT = 50 + const val CACHE_MEMORY_SIZE_PERCENTAGE = 0.1 + const val CACHE_DISK_SIZE_PERCENTAGE = 0.02 fun getDisplayNameFromDeviceContact(context: Context, id: String?): String? { var displayName: String? = null 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 40554eda8..725cf9aa9 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 @@ -11,7 +11,7 @@ import com.nextcloud.talk.contacts.ContactsRepository import com.nextcloud.talk.models.json.autocomplete.AutocompleteOverall import com.nextcloud.talk.models.json.conversations.RoomOverall -class FakeRepositoryError() : ContactsRepository { +class FakeRepositoryError : ContactsRepository { override suspend fun getContacts(searchQuery: String?, shareTypes: List): AutocompleteOverall { throw Exception("unable to fetch contacts") } 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 fd16b5f54..f5d87d919 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 @@ -12,7 +12,7 @@ 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 { +class FakeRepositorySuccess : ContactsRepository { override suspend fun getContacts(searchQuery: String?, shareTypes: List): AutocompleteOverall { return FakeItem.contactsOverall }