Skip to content

Commit

Permalink
Merge pull request #2222 from PratyushSingh07/help-fragment-mvvm
Browse files Browse the repository at this point in the history
feat: migrated help fragment to mvvm
  • Loading branch information
jawidMuhammadi authored Jul 27, 2023
2 parents a9750b9 + 5124d0c commit 58d1802
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 13 deletions.
40 changes: 27 additions & 13 deletions app/src/main/java/org/mifos/mobile/ui/fragments/HelpFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,37 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.widget.SearchView
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler
import dagger.hilt.android.AndroidEntryPoint
import org.mifos.mobile.R
import org.mifos.mobile.databinding.FragmentHelpBinding
import org.mifos.mobile.models.FAQ
import org.mifos.mobile.presenters.HelpPresenter
import org.mifos.mobile.ui.activities.base.BaseActivity
import org.mifos.mobile.ui.adapters.FAQAdapter
import org.mifos.mobile.ui.fragments.base.BaseFragment
import org.mifos.mobile.ui.views.HelpView
import org.mifos.mobile.utils.Constants
import org.mifos.mobile.utils.DividerItemDecoration
import org.mifos.mobile.utils.HelpUiState
import org.mifos.mobile.viewModels.HelpViewModel
import javax.inject.Inject

/*
~This project is licensed under the open source MPL V2.
~See https://github.com/openMF/self-service-app/blob/master/LICENSE.md
*/
@AndroidEntryPoint
class HelpFragment : BaseFragment(), HelpView {
class HelpFragment : BaseFragment() {
private var _binding: FragmentHelpBinding? = null
private val binding get() = _binding!!

@JvmField
@Inject
var faqAdapter: FAQAdapter? = null

@JvmField
@Inject
var presenter: HelpPresenter? = null
private lateinit var viewModel: HelpViewModel

private var faqArrayList: ArrayList<FAQ?>? = null
private lateinit var sweetUIErrorHandler: SweetUIErrorHandler

Expand All @@ -53,18 +53,32 @@ class HelpFragment : BaseFragment(), HelpView {
savedInstanceState: Bundle?,
): View {
_binding = FragmentHelpBinding.inflate(inflater, container, false)
viewModel = ViewModelProvider(this)[HelpViewModel::class.java]
val rootView = binding.root
setHasOptionsMenu(true)
presenter?.attachView(this)
setToolbarTitle(getString(R.string.help))
sweetUIErrorHandler = SweetUIErrorHandler(activity, rootView)
showUserInterface()
if (savedInstanceState == null) {
presenter?.loadFaq()
viewModel.loadFaq(
context?.resources?.getStringArray(R.array.faq_qs),
context?.resources?.getStringArray(R.array.faq_ans)
)
}
return rootView
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.helpUiState.observe(viewLifecycleOwner) {
when (it) {
is HelpUiState.ShowFaq -> {
showFaq(it.faqArrayList)
}
}
}
}

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putParcelableArrayList(Constants.HELP, ArrayList<Parcelable?>(faqArrayList))
Expand Down Expand Up @@ -119,7 +133,7 @@ class HelpFragment : BaseFragment(), HelpView {
}
}

override fun showFaq(faqArrayList: ArrayList<FAQ?>?) {
fun showFaq(faqArrayList: ArrayList<FAQ?>?) {
faqAdapter?.setFaqArrayList(faqArrayList)
binding.rvFaq.adapter = faqAdapter
this.faqArrayList = faqArrayList
Expand All @@ -136,8 +150,8 @@ class HelpFragment : BaseFragment(), HelpView {
}

override fun onQueryTextChange(newText: String): Boolean {
val filteredFAQList = presenter?.filterList(faqArrayList, newText)
filteredFAQList?.let {
val filteredFAQList = viewModel.filterList(faqArrayList, newText)
filteredFAQList.let {
if (it.isNotEmpty()) {
sweetUIErrorHandler.hideSweetErrorLayoutUI(
binding.rvFaq,
Expand All @@ -162,11 +176,11 @@ class HelpFragment : BaseFragment(), HelpView {
)
}

override fun showProgress() {
fun showProgress() {
showProgressBar()
}

override fun hideProgress() {
fun hideProgress() {
hideProgressBar()
}

Expand Down
7 changes: 7 additions & 0 deletions app/src/main/java/org/mifos/mobile/utils/HelpUiState.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.mifos.mobile.utils

import org.mifos.mobile.models.FAQ

sealed class HelpUiState {
data class ShowFaq(val faqArrayList: ArrayList<FAQ?>) : HelpUiState()
}
42 changes: 42 additions & 0 deletions app/src/main/java/org/mifos/mobile/viewModels/HelpViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.mifos.mobile.viewModels

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import org.mifos.mobile.models.FAQ
import org.mifos.mobile.utils.HelpUiState
import java.util.*
import javax.inject.Inject
import kotlin.collections.ArrayList

@HiltViewModel
class HelpViewModel @Inject constructor() : ViewModel() {

private val _helpUiState = MutableLiveData<HelpUiState>()
val helpUiState: LiveData<HelpUiState> get() = _helpUiState

fun loadFaq(qs: Array<String>?, ans: Array<String>?) {
val faqArrayList = ArrayList<FAQ?>()
if (qs != null) {
for (i in qs.indices) {
faqArrayList.add(FAQ(qs[i], ans?.get(i)))
}
}
_helpUiState.value = HelpUiState.ShowFaq(faqArrayList)
}

fun filterList(faqArrayList: ArrayList<FAQ?>?, query: String): ArrayList<FAQ?> {
val filteredList = ArrayList<FAQ?>()
if (faqArrayList != null) {
for (faq in faqArrayList) {
if (faq?.question?.lowercase(Locale.ROOT)
?.contains(query.lowercase(Locale.ROOT)) == true
) {
filteredList.add(faq)
}
}
}
return filteredList
}
}
75 changes: 75 additions & 0 deletions app/src/test/java/org/mifos/mobile/viewModels/HelpViewModelTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package org.mifos.mobile.viewModels

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.Observer
import junit.framework.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mifos.mobile.models.FAQ
import org.mifos.mobile.utils.HelpUiState
import org.mockito.Mock
import org.mockito.Mockito.*
import org.mockito.junit.MockitoJUnitRunner

@RunWith(MockitoJUnitRunner::class)
class HelpViewModelTest {

@get:Rule
val instantTaskExecutorRule = InstantTaskExecutorRule()

@Mock
private lateinit var mockFAQArrayList: ArrayList<FAQ?>

@Mock
private lateinit var helpUiStateObserver: Observer<HelpUiState>

private lateinit var viewModel: HelpViewModel

@Before
fun setUp() {
viewModel = HelpViewModel()
viewModel.helpUiState.observeForever(helpUiStateObserver)
}

@Test
fun testLoadFaq() {
val qs = arrayOf("Question1", "Question2")
val ans = arrayOf("Answer1", "Answer2")

viewModel.loadFaq(qs, ans)

verify(helpUiStateObserver).onChanged(
HelpUiState.ShowFaq(
arrayListOf(
FAQ(
"Question1",
"Answer1",
false
),
FAQ(
"Question2",
"Answer2",
false
)
)
)
)
verifyNoMoreInteractions(helpUiStateObserver)
}

@Test
fun testFilterList() {
val query = "app"
val mockFAQ1 = mock(FAQ::class.java)
val mockFAQ2 = mock(FAQ::class.java)

`when`(mockFAQ1.question).thenReturn("How to use the app?")
`when`(mockFAQ2.question).thenReturn("Is there a user guide available?")

val filteredList = viewModel.filterList(arrayListOf(mockFAQ1,mockFAQ2), query)

assertEquals(mockFAQ1, filteredList[0])
}
}

0 comments on commit 58d1802

Please sign in to comment.