diff --git a/holder/src/main/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionFragment.kt b/holder/src/main/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionFragment.kt index 3527990b8..8fb5207fa 100644 --- a/holder/src/main/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionFragment.kt +++ b/holder/src/main/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionFragment.kt @@ -56,19 +56,21 @@ class HolderNameSelectionFragment : Fragment(R.layout.fragment_holder_name_selec viewModel.itemsLiveData.observe(viewLifecycleOwner) { setItems(it, binding) } - binding.bottom.setButtonClick { - val selectedName = viewModel.selectedName() - if (selectedName == null) { + + viewModel.nameSelectionError.observe(viewLifecycleOwner) { noSelectionError -> + if (noSelectionError) { viewModel.nothingSelectedError() binding.bottom.showError() - } else { - viewModel.storeSelection { - navigateSafety( - actionSavedEventsSyncGreenCards( - selectedName = selectedName - ) + } + } + + binding.bottom.setButtonClick { + viewModel.storeSelection { selectedName -> + navigateSafety( + actionSavedEventsSyncGreenCards( + selectedName = selectedName ) - } + ) } } } @@ -184,7 +186,7 @@ class HolderNameSelectionFragment : Fragment(R.layout.fragment_holder_name_selec ) ) ) - }) { index -> + }) { binding.bottom.hideError() viewModel.onItemSelected(item.name) } diff --git a/holder/src/main/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionViewAdapterItem.kt b/holder/src/main/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionViewAdapterItem.kt index 755a3ed27..d4244241a 100644 --- a/holder/src/main/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionViewAdapterItem.kt +++ b/holder/src/main/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionViewAdapterItem.kt @@ -17,7 +17,7 @@ import nl.rijksoverheid.ctr.holder.databinding.ItemHolderNameSelectionViewBindin class HolderNameSelectionViewAdapterItem( private val item: HolderNameSelectionItem.ListItem, private val onDetailsButtonClicked: () -> Unit, - private val onSelected: (Int) -> Unit + private val onSelected: () -> Unit ) : BindableItem( R.layout.item_holder_name_selection_view.toLong() ) { @@ -27,12 +27,14 @@ class HolderNameSelectionViewAdapterItem( if (item.nothingSelectedError) { viewBinding.radioButton.buttonTintList = ColorStateList.valueOf(viewBinding.radioButton.context.getColor(R.color.error)) + } else { + viewBinding.radioButton.isUseMaterialThemeColors = true } viewBinding.nameTextView.text = item.name viewBinding.eventsTextView.text = item.events viewBinding.removedEventTextView.isVisible = item.willBeRemoved viewBinding.root.setOnClickListener { - onSelected(position) + onSelected() } viewBinding.detailsButton.contentDescription = "${item.name} ${viewBinding.detailsButton.text}" viewBinding.detailsButton.setOnClickListener { diff --git a/holder/src/main/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionViewModel.kt b/holder/src/main/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionViewModel.kt index a19c29003..263c915d7 100644 --- a/holder/src/main/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionViewModel.kt +++ b/holder/src/main/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionViewModel.kt @@ -21,10 +21,10 @@ abstract class HolderNameSelectionViewModel( greenCardUtil: GreenCardUtil ) : FuzzyMatchingBaseViewModel(holderDatabase, greenCardUtil) { val itemsLiveData: LiveData> = MutableLiveData() + val nameSelectionError: LiveData = MutableLiveData() abstract fun onItemSelected(selectedName: String) - abstract fun selectedName(): String? - abstract fun storeSelection(onStored: () -> Unit) + abstract fun storeSelection(onStored: (String) -> Unit) abstract fun nothingSelectedError() } @@ -43,24 +43,30 @@ class HolderNameSelectionViewModelImpl( } override fun onItemSelected(selectedName: String) { + (nameSelectionError as MutableLiveData).value = false updateItems(selectedName) } - override fun selectedName(): String? { + private fun selectedName(): String? { return itemsLiveData.value ?.filterIsInstance() ?.find { it.isSelected } ?.name } - override fun storeSelection(onStored: () -> Unit) { - val items = itemsLiveData.value?.filterIsInstance() ?: return - val itemSelected = items.find { it.isSelected } - if (itemSelected != null) { - viewModelScope.launch { - matchedEventsUseCase.selected(items.indexOf(itemSelected), matchingBlobIds) - onStored() + override fun storeSelection(onStored: (String) -> Unit) { + val selectedName = selectedName() + if (selectedName != null) { + val items = itemsLiveData.value?.filterIsInstance() ?: return + val itemSelected = items.find { it.isSelected } + if (itemSelected != null) { + viewModelScope.launch { + matchedEventsUseCase.selected(items.indexOf(itemSelected), matchingBlobIds) + onStored(selectedName) + } } + } else { + (nameSelectionError as MutableLiveData).value = true } } diff --git a/holder/src/test/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionViewModelImplTest.kt b/holder/src/test/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionViewModelImplTest.kt index 92fd62ee1..3c113d198 100644 --- a/holder/src/test/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionViewModelImplTest.kt +++ b/holder/src/test/java/nl/rijksoverheid/ctr/holder/fuzzy_matching/HolderNameSelectionViewModelImplTest.kt @@ -19,6 +19,8 @@ import nl.rijksoverheid.ctr.holder.your_events.utils.YourEventsFragmentUtil import nl.rijksoverheid.ctr.persistence.database.HolderDatabase import nl.rijksoverheid.ctr.persistence.database.entities.EventGroupEntity import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Rule import org.junit.Test @@ -81,7 +83,6 @@ class HolderNameSelectionViewModelImplTest { val items = viewModel.itemsLiveData.getOrAwaitValue() - assertEquals("firstNameA2", viewModel.selectedName()) assertEquals(false, (items[1] as HolderNameSelectionItem.ListItem).isSelected) assertEquals(true, (items[1] as HolderNameSelectionItem.ListItem).willBeRemoved) assertEquals(false, (items[1] as HolderNameSelectionItem.ListItem).nothingSelectedError) @@ -139,6 +140,49 @@ class HolderNameSelectionViewModelImplTest { assertEquals(0, itemSlot.captured) } + @Test + fun `given no name is selected, when store selection, then nothing selected error`() = runTest { + mockEvents() + + val viewModel = HolderNameSelectionViewModelImpl( + matchedEventsUseCase, + getRemoteProtocolFromEventGroupUseCase, + selectionDataUtil, + yourEventsFragmentUtil, + holderDatabase, + greenCardUtil, + matchingBlobIds + ) + + viewModel.storeSelection { } + + assertTrue(viewModel.nameSelectionError.getOrAwaitValue()) + } + + @Test + fun `given name no name is selected yet, when select name and store selection, then no error`() = + runTest { + mockEvents() + coEvery { matchedEventsUseCase.selected(any(), any()) } just runs + + val viewModel = HolderNameSelectionViewModelImpl( + matchedEventsUseCase, + getRemoteProtocolFromEventGroupUseCase, + selectionDataUtil, + yourEventsFragmentUtil, + holderDatabase, + greenCardUtil, + matchingBlobIds + ) + + viewModel.onItemSelected("firstNameA1") + viewModel.storeSelection { + assertEquals("firstNameA1", it) + } + + assertFalse(viewModel.nameSelectionError.getOrAwaitValue()) + } + private suspend fun mockEvents() { coEvery { holderDatabase.eventGroupDao().getAll() } returns getEvents() val eventSlot = slot()