diff --git a/app/build.gradle b/app/build.gradle index e7678fb55..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 { @@ -333,6 +335,14 @@ 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") + 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 0746d7a61..75fc8c1bd 100644 --- a/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsActivityCompose.kt @@ -13,10 +13,8 @@ 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 import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -35,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 @@ -61,9 +60,8 @@ 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.activities.BaseActivity import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser @@ -72,7 +70,7 @@ 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 @@ -83,9 +81,12 @@ class ContactsActivityCompose : ComponentActivity() { super.onCreate(savedInstanceState) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) contactsViewModel = ViewModelProvider(this, viewModelFactory)[ContactsViewModel::class.java] - setContent { - MaterialTheme { + val colorScheme = viewThemeUtils.getColorScheme(this) + val uiState = contactsViewModel.contactsViewState.collectAsState() + MaterialTheme( + colorScheme = colorScheme + ) { val context = LocalContext.current Scaffold( topBar = { @@ -96,7 +97,6 @@ class ContactsActivityCompose : ComponentActivity() { ) }, content = { - val uiState = contactsViewModel.contactsViewState.collectAsState() Column(Modifier.padding(it)) { ConversationCreationOptions(context = context) ContactsList( @@ -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") } } } @@ -205,15 +206,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) ) @@ -246,8 +242,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() @@ -282,13 +280,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) + contentDescription = null ) Text( modifier = Modifier @@ -308,13 +306,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) + contentDescription = null ) Text( modifier = Modifier diff --git a/app/src/main/java/com/nextcloud/talk/contacts/ContactsApplication.kt b/app/src/main/java/com/nextcloud/talk/contacts/ContactsApplication.kt new file mode 100644 index 000000000..dbbfe4d3c --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/contacts/ContactsApplication.kt @@ -0,0 +1,36 @@ +/* + * 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 +import com.nextcloud.talk.utils.ContactUtils + +class ContactsApplication : Application(), ImageLoaderFactory { + override fun newImageLoader(): ImageLoader { + val imageLoader = ImageLoader.Builder(this) + .memoryCache { + MemoryCache.Builder(this) + .maxSizePercent(ContactUtils.CACHE_MEMORY_SIZE_PERCENTAGE) + .build() + } + .diskCache { + DiskCache.Builder() + .maxSizePercent(ContactUtils.CACHE_DISK_SIZE_PERCENTAGE) + .directory(cacheDir) + .build() + } + .logger(DebugLogger()) + .build() + return imageLoader + } +} 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/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/SearchComponent.kt b/app/src/main/java/com/nextcloud/talk/contacts/SearchComponent.kt index 7adaef8bf..f7ba7d61b 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,13 +16,10 @@ 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.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 @@ -34,82 +30,65 @@ 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) - .background(Color.White) - ) { - val keyboardController = LocalSoftwareKeyboardController.current - TextField( - modifier = Modifier - .fillMaxWidth(), - value = text, - onValueChange = { onTextChange(it) }, - placeholder = { - Text( - text = stringResource(R.string.nc_search), - color = Color.DarkGray - ) - }, + .height(60.dp), + value = text, + onValueChange = { onTextChange(it) }, + placeholder = { + Text( + text = stringResource(R.string.nc_search) + ) + }, - textStyle = TextStyle( - color = Color.Black, - fontSize = 16.sp - ), - singleLine = true, - leadingIcon = { + 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()) { IconButton( onClick = { onTextChange("") - contactsViewModel.updateSearchState(false) } ) { Icon( - imageVector = Icons.AutoMirrored.Default.ArrowBack, - contentDescription = stringResource(R.string.back_button), - tint = Color.Black + imageVector = Icons.Default.Close, + contentDescription = stringResource(R.string.close_icon) ) } - }, + } + }, - trailingIcon = { - if (text.isNotEmpty()) { - IconButton( - onClick = { - onTextChange("") - } - ) { - Icon( - imageVector = Icons.Default.Close, - contentDescription = stringResource(R.string.close_icon), - tint = Color.Black - ) - } + keyboardOptions = KeyboardOptions( + imeAction = ImeAction.Search + ), + + keyboardActions = KeyboardActions( + onSearch = { + if (text.trim().isNotEmpty()) { + keyboardController?.hide() + } else { + return@KeyboardActions } - }, - - keyboardOptions = KeyboardOptions( - imeAction = ImeAction.Search - ), - - keyboardActions = KeyboardActions( - onSearch = { - if (text.trim().isNotEmpty()) { - keyboardController?.hide() - } else { - return@KeyboardActions - } - } - ), - maxLines = 1, - colors = TextFieldDefaults.colors( - focusedContainerColor = Color.White, - unfocusedContainerColor = Color.White, - disabledContainerColor = Color.White, - focusedTextColor = Color.Black, - cursorColor = Color.Black - ) - ) - } + } + ), + maxLines = 1 + ) } 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/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/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..7bb905b43 --- /dev/null +++ b/app/src/test/java/com/nextcloud/talk/contacts/ContactsViewModelTest.kt @@ -0,0 +1,126 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2024 Sowjanya Kota + * 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.FakeRepositoryError +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 = 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 `test error contacts state`() = + 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`() { + 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) + 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/apiService/FakeItem.kt b/app/src/test/java/com/nextcloud/talk/contacts/apiService/FakeItem.kt new file mode 100644 index 000000000..acfcbfe30 --- /dev/null +++ b/app/src/test/java/com/nextcloud/talk/contacts/apiService/FakeItem.kt @@ -0,0 +1,58 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2024 Sowjanya Kota + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +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 = + 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 + ) + ) + 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/FakeRepositoryError.kt b/app/src/test/java/com/nextcloud/talk/contacts/repository/FakeRepositoryError.kt new file mode 100644 index 000000000..725cf9aa9 --- /dev/null +++ b/app/src/test/java/com/nextcloud/talk/contacts/repository/FakeRepositoryError.kt @@ -0,0 +1,31 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2024 Sowjanya Kota + * 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 { + throw Exception("unable to fetch contacts") + } + + override suspend fun createRoom( + roomType: String, + sourceType: String, + userId: String, + conversationName: String? + ): RoomOverall { + throw Exception("unable to create room") + } + + override fun getImageUri(avatarId: String, requestBigSize: Boolean): String { + return "https://mydoman.com/index.php/avatar/$avatarId/512" + } +} 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..f5d87d919 --- /dev/null +++ b/app/src/test/java/com/nextcloud/talk/contacts/repository/FakeRepositorySuccess.kt @@ -0,0 +1,32 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2024 Sowjanya Kota + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +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 { + return FakeItem.contactsOverall + } + + override suspend fun createRoom( + roomType: String, + sourceType: String, + userId: String, + conversationName: String? + ): RoomOverall { + return FakeItem.roomOverall + } + + override fun getImageUri(avatarId: String, requestBigSize: Boolean): String { + return "https://mydomain.com/index.php/avatar/$avatarId/512" + } +} diff --git a/build.gradle b/build.gradle index d2f3e8054..6a0ab2789 100644 --- a/build.gradle +++ b/build.gradle @@ -11,12 +11,10 @@ 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..1fa1435c6 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -4,13 +4,13 @@ true true - - - - + + + + @@ -39,7 +39,10 @@ - + + + + @@ -156,6 +159,7 @@ + @@ -232,6 +236,7 @@ + @@ -294,6 +299,14 @@ + + + + + + + + @@ -326,6 +339,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -342,6 +399,14 @@ + + + + + + + + @@ -355,6 +420,11 @@ + + + + + @@ -376,6 +446,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4902,6 +5042,14 @@ + + + + + + + + @@ -5860,7 +6008,7 @@ - +