From efd682761e5a7fb1e56c292671a76c1a1873fa51 Mon Sep 17 00:00:00 2001 From: Pratyush Singh Date: Thu, 15 Jun 2023 01:01:55 +0530 Subject: [PATCH 01/35] feat: coroutines dependency --- app/build.gradle | 5 ++++- build.gradle | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index d808e8ae6..780cee0af 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -154,7 +154,10 @@ dependencies { //Biometric Authentication implementation "androidx.biometric:biometric:$rootProject.biometric" - // Unit tests dependencies + // Coroutines + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines" + + // Unit tests dependencies testImplementation "junit:junit:$rootProject.jUnitVersion" testImplementation "org.mockito:mockito-core:$rootProject.mockitoVersion" diff --git a/build.gradle b/build.gradle index 942acd60c..aa36c6c1c 100644 --- a/build.gradle +++ b/build.gradle @@ -68,6 +68,7 @@ ext { kotlinVersion = '1.6.10' tableViewVersion = '0.8.9.4' biometric = '1.1.0' + coroutines = '1.6.4' jUnitVersion = '4.13.2' mockitoVersion = '5.3.1' From f2052096298226d729e7bf0d6d2aaed8718f26c5 Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Fri, 16 Jun 2023 11:22:50 +0530 Subject: [PATCH 02/35] feat : Migrated Registration Fragment to MVVM --- .../ui/fragments/RegistrationFragment.kt | 316 +++++++++--------- .../viewModels/RegistrationViewModel.kt | 65 ++++ .../RegistrationViewModelFactory.kt | 19 ++ app/src/main/res/values-ar/strings.xml | 2 +- app/src/main/res/values-my/strings.xml | 4 +- 5 files changed, 252 insertions(+), 154 deletions(-) create mode 100644 app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt create mode 100644 app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt index 4a15701b2..d0d4f05e1 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt @@ -4,35 +4,37 @@ import android.graphics.PorterDuff import android.os.Bundle import android.text.Editable import android.text.TextWatcher -import android.util.Patterns import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.RadioButton import android.widget.TextView +import androidx.lifecycle.ViewModelProvider import com.hbb20.CountryCodePicker import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentRegistrationBinding import org.mifos.mobile.models.register.RegisterPayload -import org.mifos.mobile.presenters.RegistrationPresenter import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.fragments.base.BaseFragment -import org.mifos.mobile.ui.views.RegistrationView +import org.mifos.mobile.utils.MFErrorParser import org.mifos.mobile.utils.Network import org.mifos.mobile.utils.PasswordStrength import org.mifos.mobile.utils.Toaster +import org.mifos.mobile.viewModels.RegistrationViewModel +import org.mifos.mobile.viewModels.RegistrationViewModelFactory import javax.inject.Inject /** * Created by dilpreet on 31/7/17. */ -class RegistrationFragment : BaseFragment(), RegistrationView { +class RegistrationFragment : BaseFragment() { private var _binding: FragmentRegistrationBinding? = null private val binding get() = _binding!! + private lateinit var viewModel : RegistrationViewModel - @JvmField @Inject - var presenter: RegistrationPresenter? = null + lateinit var viewModelFactory: RegistrationViewModelFactory + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -41,52 +43,65 @@ class RegistrationFragment : BaseFragment(), RegistrationView { _binding = FragmentRegistrationBinding.inflate(inflater, container, false) val rootView = binding.root (activity as BaseActivity?)?.activityComponent?.inject(this) - presenter?.attachView(this) - binding.progressBar.visibility = View.GONE - binding.passwordStrength.visibility = View.GONE - binding.etPassword.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {} - override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) { - if (charSequence.isEmpty()) { - binding.progressBar.visibility = View.GONE - binding.passwordStrength.visibility = View.GONE - } else { - binding.progressBar.visibility = View.VISIBLE - binding.passwordStrength.visibility = View.VISIBLE - updatePasswordStrengthView(charSequence.toString()) + viewModel = ViewModelProvider(this, viewModelFactory)[RegistrationViewModel::class.java] + with(binding) { + progressBar.visibility = View.GONE + passwordStrength.visibility = View.GONE + etPassword.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int ) {} + override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) { + if (charSequence.isEmpty()) { + progressBar.visibility = View.GONE + passwordStrength.visibility = View.GONE + } else { + progressBar.visibility = View.VISIBLE + passwordStrength.visibility = View.VISIBLE + updatePasswordStrengthView(charSequence.toString()) + } } - } - - override fun afterTextChanged(editable: Editable) {} - }) + override fun afterTextChanged(editable: Editable) {} + }) + } return rootView } private fun updatePasswordStrengthView(password: String) { - if (TextView.VISIBLE != binding.passwordStrength.visibility) return - if (password.isEmpty()) { - binding.passwordStrength.text = "" - binding.progressBar.progress = 0 - return - } - val str = PasswordStrength.calculateStrength(password) - binding.passwordStrength.text = str.getText(context) - binding.passwordStrength.setTextColor(str.color) - val mode = PorterDuff.Mode.SRC_IN - binding.progressBar.progressDrawable?.setColorFilter(str.color, mode) - if (str.getText(context) == getString(R.string.password_strength_weak)) { - binding.progressBar.progress = 25 - } else if (str.getText(context) == getString(R.string.password_strength_medium)) { - binding.progressBar.progress = 50 - } else if (str.getText(context) == getString(R.string.password_strength_strong)) { - binding.progressBar.progress = 75 - } else { - binding.progressBar.progress = 100 + with(binding) { + if (TextView.VISIBLE != passwordStrength.visibility) return + if (password.isEmpty()) { + passwordStrength.text = "" + progressBar.progress = 0 + return + } + val str = PasswordStrength.calculateStrength(password) + passwordStrength.text = str.getText(context) + passwordStrength.setTextColor(str.color) + val mode = PorterDuff.Mode.SRC_IN + progressBar.progressDrawable?.setColorFilter(str.color, mode) + if (str.getText(context) == getString(R.string.password_strength_weak)) { + progressBar.progress = 25 + } else if (str.getText(context) == getString(R.string.password_strength_medium)) { + progressBar.progress = 50 + } else if (str.getText(context) == getString(R.string.password_strength_strong)) { + progressBar.progress = 75 + } else { + progressBar.progress = 100 + } } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + viewModel.readRegistrationResultSuccess.observe(viewLifecycleOwner) { registrationResultSuccess -> + hideProgress() + if (registrationResultSuccess == true) { + showRegisteredSuccessfully() + } else { + showError(MFErrorParser.errorMessage(viewModel.readExceptionOnRegistration)) + } + } + binding.btnRegister.setOnClickListener { registerClicked() } @@ -94,120 +109,120 @@ class RegistrationFragment : BaseFragment(), RegistrationView { private fun registerClicked() { if (areFieldsValidated()) { - val radioButton = binding.rgVerificationMode.checkedRadioButtonId.let { - binding.root.findViewById(it) - } - val payload = RegisterPayload() - payload.accountNumber = binding.etAccountNumber.text.toString() - payload.authenticationMode = radioButton?.text.toString() - payload.email = binding.etEmail.text.toString() - payload.firstName = binding.etFirstName.text.toString() - payload.lastName = binding.etLastName.text.toString() - payload.mobileNumber = - binding.countryCodePicker.selectedCountryCode.toString() + binding.etPhoneNumber.text.toString() - if (binding.etPassword.text.toString() != binding.etConfirmPassword.text.toString()) { - Toaster.show(binding.root, getString(R.string.error_password_not_match)) - return - } else { - payload.password = binding.etPassword.text.toString() - } - payload.password = binding.etPassword.text.toString() - payload.username = binding.etUsername.text.toString().replace(" ", "") - if (Network.isConnected(context)) { - presenter?.registerUser(payload) - } else { - Toaster.show(binding.root, getString(R.string.no_internet_connection)) + with(binding) { + val radioButton = rgVerificationMode.checkedRadioButtonId.let { + root.findViewById(it) + } + val payload = RegisterPayload().apply { + accountNumber = etAccountNumber.text.toString() + authenticationMode = radioButton?.text.toString() + email = etEmail.text.toString() + firstName = etFirstName.text.toString() + lastName = etLastName.text.toString() + mobileNumber = + countryCodePicker.selectedCountryCode.toString() + etPhoneNumber.text.toString() + if (etPassword.text.toString() != etConfirmPassword.text.toString()) { + Toaster.show(root, getString(R.string.error_password_not_match)) + return + } else { + password = etPassword.text.toString() + } + password = etPassword.text.toString() + username = etUsername.text.toString().replace(" ", "") + } + if (Network.isConnected(context)) { + showProgress() + viewModel.registerUser(payload) + } else { + Toaster.show(root, getString(R.string.no_internet_connection)) + } } } } private fun areFieldsValidated(): Boolean { val rootView = binding.root - if (binding.etAccountNumber.text.toString().trim { it <= ' ' }.isEmpty()) { - Toaster.show( - rootView, - getString(R.string.error_validation_blank, getString(R.string.account_number)), - ) - return false - } else if (binding.etUsername.text.toString().trim { it <= ' ' }.isEmpty()) { - Toaster.show( - rootView, - getString(R.string.error_validation_blank, getString(R.string.username)), - ) - return false - } else if (binding.etUsername.text.toString().trim { it <= ' ' }.length < 6) { - Toaster.show(rootView, getString(R.string.error_username_greater_than_six)) - return false - } else if (binding.etUsername.text.toString().trim { it <= ' ' }.contains(" ")) { - Toaster.show( - rootView, - getString( - R.string.error_validation_cannot_contain_spaces, - getString(R.string.username), - getString(R.string.not_contain_username), - ), - ) - return false - } else if (binding.etFirstName.text?.isEmpty() == true) { - Toaster.show( - rootView, - getString(R.string.error_validation_blank, getString(R.string.first_name)), - ) - return false - } else if (binding.etLastName.text.toString().trim { it <= ' ' }.isEmpty()) { - Toaster.show( - rootView, - getString(R.string.error_validation_blank, getString(R.string.last_name)), - ) - return false - } else if (binding.etEmail.text.toString().trim { it <= ' ' }.isEmpty()) { - Toaster.show( - rootView, - getString(R.string.error_validation_blank, getString(R.string.email)), - ) - return false - } else if (binding.etPassword.text.toString().trim { it <= ' ' }.isEmpty()) { - Toaster.show( - rootView, - getString(R.string.error_validation_blank, getString(R.string.password)), - ) - return false - } else if (binding.etPassword.text.toString().trim { it <= ' ' }.length - < binding.etPassword.text.toString().length - ) { - Toaster.show( - rootView, - getString( - R.string.error_validation_cannot_contain_leading_or_trailing_spaces, - getString(R.string.password), - ), - ) - return false - } else if (!Patterns.EMAIL_ADDRESS.matcher( - binding.etEmail.text.toString().trim { it <= ' ' }, - ) - .matches() - ) { - Toaster.show(rootView, getString(R.string.error_invalid_email)) - return false - } else if (binding.etPassword.text.toString().trim { it <= ' ' }.length < 6) { - Toaster.show( - rootView, - getString( - R.string.error_validation_minimum_chars, - getString(R.string.password), - resources.getInteger(R.integer.password_minimum_length), - ), - ) - return false - } else if (!isPhoneNumberValid(binding.countryCodePicker)) { - Toaster.show(rootView, getString(R.string.invalid_phn_number)) - return false + with(binding) { + if (viewModel.isInputFieldBlank(etAccountNumber.text.toString())) { + Toaster.show( + rootView, + getString(R.string.error_validation_blank, getString(R.string.account_number)), + ) + return false + } else if (viewModel.isInputFieldBlank(etUsername.text.toString())) { + Toaster.show( + rootView, + getString(R.string.error_validation_blank, getString(R.string.username)), + ) + return false + } else if (viewModel.isInputLengthInadequate(etUsername.text.toString())) { + Toaster.show(rootView, getString(R.string.error_username_greater_than_six)) + return false + } else if (viewModel.inputHasSpaces(etUsername.text.toString())) { + Toaster.show( + rootView, + getString( + R.string.error_validation_cannot_contain_spaces, + getString(R.string.username), + getString(R.string.not_contain_username), + ), + ) + return false + } else if (viewModel.isInputFieldBlank(etFirstName.text.toString())) { + Toaster.show( + rootView, + getString(R.string.error_validation_blank, getString(R.string.first_name)), + ) + return false + } else if (viewModel.isInputFieldBlank(etLastName.text.toString())) { + Toaster.show( + rootView, + getString(R.string.error_validation_blank, getString(R.string.last_name)), + ) + return false + } else if (viewModel.isInputFieldBlank(etEmail.text.toString())) { + Toaster.show( + rootView, + getString(R.string.error_validation_blank, getString(R.string.email)), + ) + return false + } else if (viewModel.isInputFieldBlank(etPassword.text.toString())) { + Toaster.show( + rootView, + getString(R.string.error_validation_blank, getString(R.string.password)), + ) + return false + } else if (viewModel.hasLeadingTrailingSpaces(etPassword.text.toString())) { + Toaster.show( + rootView, + getString( + R.string.error_validation_cannot_contain_leading_or_trailing_spaces, + getString(R.string.password), + ), + ) + return false + } else if (viewModel.isEmailInvalid(etEmail.text.toString())) { + Toaster.show(rootView, getString(R.string.error_invalid_email)) + return false + } else if (viewModel.isInputLengthInadequate(etPassword.text.toString())) { + Toaster.show( + rootView, + getString( + R.string.error_validation_minimum_chars, + getString(R.string.password), + resources.getInteger(R.integer.password_minimum_length), + ), + ) + return false + } else if (!isPhoneNumberValid(countryCodePicker)) { + Toaster.show(rootView, getString(R.string.invalid_phn_number)) + return false + } + return true } - return true } - override fun showRegisteredSuccessfully() { + private fun showRegisteredSuccessfully() { (activity as BaseActivity?)?.replaceFragment( RegistrationVerificationFragment.newInstance(), true, @@ -215,21 +230,20 @@ class RegistrationFragment : BaseFragment(), RegistrationView { ) } - override fun showError(msg: String?) { + fun showError(msg: String?) { Toaster.show(binding.root, msg) } - override fun showProgress() { + fun showProgress() { showMifosProgressDialog(getString(R.string.sign_up)) } - override fun hideProgress() { + fun hideProgress() { hideMifosProgressDialog() } override fun onDestroyView() { super.onDestroyView() - presenter?.detachView() _binding = null } diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt new file mode 100644 index 000000000..b00fae478 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt @@ -0,0 +1,65 @@ +package org.mifos.mobile.viewModels + +import android.util.Patterns +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.observers.DisposableObserver +import io.reactivex.schedulers.Schedulers +import okhttp3.ResponseBody +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.register.RegisterPayload +import javax.inject.Inject + +class RegistrationViewModel @Inject constructor(var dataManager : DataManager?) : ViewModel() { + private val compositeDisposables: CompositeDisposable = CompositeDisposable() + + private var registrationResultSuccess = MutableLiveData() + val readRegistrationResultSuccess : LiveData get() = registrationResultSuccess + private var exceptionOnRegistration : Throwable? = null + val readExceptionOnRegistration : Throwable get() = exceptionOnRegistration!! + + fun isInputFieldBlank(fieldText : String) : Boolean { + return fieldText.trim { it <= ' '}.isEmpty() + } + + fun isInputLengthInadequate(fieldText : String) : Boolean { + return fieldText.trim { it <= ' '}.length < 6 + } + + fun inputHasSpaces(fieldText: String) : Boolean { + return fieldText.trim { it <= ' '}.contains(" ") + } + + fun hasLeadingTrailingSpaces(fieldText: String) : Boolean { + return fieldText.trim { it <= ' ' }.length < fieldText.length + } + + fun isEmailInvalid(emailText : String) : Boolean { + return !Patterns.EMAIL_ADDRESS.matcher(emailText.trim { it <= ' ' }).matches() + } + + fun registerUser(registerPayload: RegisterPayload?) { + dataManager?.registerUser(registerPayload) + ?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribeOn(Schedulers.io()) + ?.subscribeWith(object : DisposableObserver() { + override fun onComplete() {} + override fun onError(e: Throwable) { + exceptionOnRegistration = e + registrationResultSuccess.value = false + } + + override fun onNext(responseBody: ResponseBody) { + registrationResultSuccess.value = true + } + })?.let { compositeDisposables.add(it) } + } + + override fun onCleared() { + super.onCleared() + compositeDisposables.clear() + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt new file mode 100644 index 000000000..dd0d3089b --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt @@ -0,0 +1,19 @@ +package org.mifos.mobile.viewModels + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.injection.PerActivity +import javax.inject.Inject + +@PerActivity +class RegistrationViewModelFactory @Inject constructor(private val dataManager: DataManager?) : + ViewModelProvider.Factory { + + override fun create(modelClass: Class): T { + if(modelClass.isAssignableFrom(RegistrationViewModel::class.java)) { + return RegistrationViewModel(dataManager) as T + } + throw IllegalArgumentException("Unknown ViewModel class: " + modelClass.name) + } +} \ No newline at end of file diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 33e648662..edc555e98 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -148,7 +148,7 @@ اسم المتسخدم / كلمة المرور غير صحيحة خطأ في تحميل الاستجابة من الخادم %1$s لا يمكن أن يكون فارغًا - لا يمكن أن يكون %1$s أقل من %2$s من الأحرف + لا يمكن أن يكون %1$s أقل من %2$d من الأحرف لا يمكن أن تحتوي %1$s على %2$s لا يمكن بد %1$s أو          نهاية مع مساحة فارغة diff --git a/app/src/main/res/values-my/strings.xml b/app/src/main/res/values-my/strings.xml index c3020c08e..2443df7ef 100644 --- a/app/src/main/res/values-my/strings.xml +++ b/app/src/main/res/values-my/strings.xml @@ -148,9 +148,9 @@ မှားနေသောအသုံးပြုသူအမည် / Password ကို server ကနေတင်ပေးမှုအမှားတုန့်ပြန် %1$s ကိုအလွတ်မဖွစျနိုငျ - %1$s ကို %2$ ဃဇာတ်ကောင်ထက်လျော့နည်းမဖွစျနိုငျ + %1$s ကို %2$d ဃဇာတ်ကောင်ထက်လျော့နည်းမဖွစျနိုငျ %1$s ကို %2$s ကိုဆံ့မခံနိုင်သည် - s ကိုစတင်မနိုင် %1$ သို့မဟုတ်ဗလာဖြင့်အဆုံး + ကိုစတင်မနိုင် %1$s သို့မဟုတ်ဗလာဖြင့်အဆုံး ပြည်တွင်းရေး server ကိုအမှား,ျေးဇူးပြု.ထပ်ကြိုးစား မှားယွင်းနေသည်တင်clientကိုစာရင်း ချေးငွေအကောင့်စာရင်းထဲတွင်တင်ပေးမှုအမှား From 927d4784e77bd1247c8a08b133168c8f09a3233c Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Sat, 17 Jun 2023 15:53:18 +0530 Subject: [PATCH 03/35] feat : Migrating registration verification fragment to MVVM --- .../RegistrationVerificationFragment.kt | 37 ++++++++++----- .../RegistrationVerificationViewModel.kt | 46 +++++++++++++++++++ ...egistrationVerificationViewModelFactory.kt | 17 +++++++ 3 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModel.kt create mode 100644 app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModelFactory.kt diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt index 7962982b9..d75c96064 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt @@ -6,27 +6,30 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast +import androidx.lifecycle.ViewModelProvider import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentRegistrationVerificationBinding import org.mifos.mobile.models.register.UserVerify -import org.mifos.mobile.presenters.RegistrationVerificationPresenter import org.mifos.mobile.ui.activities.LoginActivity import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.fragments.base.BaseFragment -import org.mifos.mobile.ui.views.RegistrationVerificationView +import org.mifos.mobile.utils.MFErrorParser import org.mifos.mobile.utils.Toaster +import org.mifos.mobile.viewModels.RegistrationVerificationViewModel +import org.mifos.mobile.viewModels.RegistrationVerificationViewModelFactory import javax.inject.Inject /** * Created by dilpreet on 31/7/17. */ -class RegistrationVerificationFragment : BaseFragment(), RegistrationVerificationView { +class RegistrationVerificationFragment : BaseFragment() { private var _binding: FragmentRegistrationVerificationBinding? = null private val binding get() = _binding!! + private lateinit var viewModel : RegistrationVerificationViewModel - @JvmField @Inject - var presenter: RegistrationVerificationPresenter? = null + lateinit var viewModelFactory : RegistrationVerificationViewModelFactory + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -35,12 +38,22 @@ class RegistrationVerificationFragment : BaseFragment(), RegistrationVerificatio _binding = FragmentRegistrationVerificationBinding.inflate(inflater, container, false) val rootView = binding.root (activity as BaseActivity?)?.activityComponent?.inject(this) - presenter?.attachView(this) + viewModel = ViewModelProvider(this, viewModelFactory)[RegistrationVerificationViewModel::class.java] return rootView } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + viewModel.readVerificationResultSuccess.observe(viewLifecycleOwner) { verificationResultSuccess -> + hideProgress() + if (verificationResultSuccess == true) { + showVerifiedSuccessfully() + } else { + showError(MFErrorParser.errorMessage(viewModel.readExceptionOnVerification)) + } + } + binding.btnVerify.setOnClickListener { verifyClicked() } @@ -50,30 +63,30 @@ class RegistrationVerificationFragment : BaseFragment(), RegistrationVerificatio val userVerify = UserVerify() userVerify.authenticationToken = binding.etAuthenticationToken.text.toString() userVerify.requestId = binding.etRequestId.text.toString() - presenter?.verifyUser(userVerify) + showProgress() + viewModel.verifyUser(userVerify) } - override fun showVerifiedSuccessfully() { + private fun showVerifiedSuccessfully() { startActivity(Intent(activity, LoginActivity::class.java)) Toast.makeText(context, getString(R.string.verified), Toast.LENGTH_SHORT).show() activity?.finish() } - override fun showError(msg: String?) { + fun showError(msg: String?) { Toaster.show(binding.root, msg) } - override fun showProgress() { + fun showProgress() { showMifosProgressDialog(getString(R.string.verifying)) } - override fun hideProgress() { + fun hideProgress() { hideMifosProgressDialog() } override fun onDestroyView() { super.onDestroyView() - presenter?.detachView() _binding = null } diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModel.kt new file mode 100644 index 000000000..e21af41b3 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModel.kt @@ -0,0 +1,46 @@ +package org.mifos.mobile.viewModels + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.observers.DisposableObserver +import io.reactivex.schedulers.Schedulers +import okhttp3.ResponseBody +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.register.UserVerify +import javax.inject.Inject + +class RegistrationVerificationViewModel @Inject constructor(private val dataManager : DataManager?) : ViewModel() { + + private val compositeDisposables : CompositeDisposable = CompositeDisposable() + + private var verificationResultSuccess = MutableLiveData() + val readVerificationResultSuccess : LiveData get() = verificationResultSuccess + + private var exceptionOnVerification : Throwable? = null + val readExceptionOnVerification : Throwable? get() = exceptionOnVerification!! + + fun verifyUser(userVerify: UserVerify?) { + dataManager?.verifyUser(userVerify) + ?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribeOn(Schedulers.io()) + ?.subscribeWith(object : DisposableObserver() { + override fun onComplete() {} + override fun onError(e: Throwable) { + exceptionOnVerification = e + verificationResultSuccess.value = false + } + + override fun onNext(responseBody: ResponseBody) { + verificationResultSuccess.value = true + } + })?.let { compositeDisposables.add(it) } + } + + override fun onCleared() { + super.onCleared() + compositeDisposables.clear() + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModelFactory.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModelFactory.kt new file mode 100644 index 000000000..0d0fc5e79 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModelFactory.kt @@ -0,0 +1,17 @@ +package org.mifos.mobile.viewModels + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import org.mifos.mobile.api.DataManager +import javax.inject.Inject + +class RegistrationVerificationViewModelFactory @Inject constructor(private val dataManager: DataManager?) + : ViewModelProvider.Factory { + + override fun create(modelClass: Class): T { + if (modelClass.isAssignableFrom(RegistrationVerificationViewModel::class.java)) { + return RegistrationVerificationViewModel(dataManager) as T + } + throw IllegalArgumentException("Unknown ViewModel class: " + modelClass.name) + } +} \ No newline at end of file From 32ea26ce367fd195661d5b5b8e9ee4c16a4d5682 Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Sun, 18 Jun 2023 23:35:22 +0530 Subject: [PATCH 04/35] feat : migrating notification fragment to MVVM --- .../ui/fragments/NotificationFragment.kt | 44 +++++++++++++------ .../viewModels/NotificationViewModel.kt | 43 ++++++++++++++++++ .../NotificationViewModelFactory.kt | 19 ++++++++ 3 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt create mode 100644 app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModelFactory.kt diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt index 490cb028b..c08521874 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt @@ -5,6 +5,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast +import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler @@ -12,25 +13,25 @@ import org.mifos.mobile.BuildConfig import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentNotificationBinding import org.mifos.mobile.models.notification.MifosNotification -import org.mifos.mobile.presenters.NotificationPresenter import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.adapters.NotificationAdapter import org.mifos.mobile.ui.fragments.base.BaseFragment -import org.mifos.mobile.ui.views.NotificationView import org.mifos.mobile.utils.DividerItemDecoration import org.mifos.mobile.utils.Network +import org.mifos.mobile.viewModels.NotificationViewModel +import org.mifos.mobile.viewModels.NotificationViewModelFactory import javax.inject.Inject /** * Created by dilpreet on 13/9/17. */ -class NotificationFragment : BaseFragment(), NotificationView, OnRefreshListener { +class NotificationFragment : BaseFragment(), OnRefreshListener { private var _binding: FragmentNotificationBinding? = null private val binding get() = _binding!! + private lateinit var viewModel : NotificationViewModel - @JvmField @Inject - var presenter: NotificationPresenter? = null + lateinit var viewModelFactory : NotificationViewModelFactory @JvmField @Inject @@ -49,6 +50,7 @@ class NotificationFragment : BaseFragment(), NotificationView, OnRefreshListener ): View { _binding = FragmentNotificationBinding.inflate(inflater, container, false) val rootView = binding.root + viewModel = ViewModelProvider(this, viewModelFactory)[NotificationViewModel::class.java] sweetUIErrorHandler = SweetUIErrorHandler(activity, rootView) val layoutManager = LinearLayoutManager(activity) layoutManager.orientation = LinearLayoutManager.VERTICAL @@ -67,12 +69,11 @@ class NotificationFragment : BaseFragment(), NotificationView, OnRefreshListener R.color.red_light, ) binding.swipeNotificationContainer.setOnRefreshListener(this) - presenter?.attachView(this) - presenter?.loadNotifications() + loadNotifications() return rootView } - override fun showNotifications(notifications: List?) { + private fun showNotifications(notifications: List?) { if (BuildConfig.DEBUG && notifications == null) { error("Assertion failed") } @@ -88,7 +89,7 @@ class NotificationFragment : BaseFragment(), NotificationView, OnRefreshListener } } - override fun showError(msg: String?) { + fun showError(msg: String?) { if (!Network.isConnected(activity)) { sweetUIErrorHandler?.showSweetNoInternetUI( binding.rvNotifications, @@ -106,18 +107,33 @@ class NotificationFragment : BaseFragment(), NotificationView, OnRefreshListener override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + viewModel.readLoadNotificationsResultSuccess.observe(viewLifecycleOwner) { loadNotificationsResultSuccess -> + hideProgress() + if(loadNotificationsResultSuccess == true) { + showNotifications(viewModel.readLoadedNotifications) + } else { + showError(context?.getString(R.string.notification)) + } + } + binding.layoutError.btnTryAgain.setOnClickListener { retryClicked() } } - fun retryClicked() { + private fun loadNotifications() { + showProgress() + viewModel.loadNotifications() + } + + private fun retryClicked() { if (Network.isConnected(context)) { sweetUIErrorHandler?.hideSweetErrorLayoutUI( binding.rvNotifications, binding.layoutError.root, ) - presenter?.loadNotifications() + loadNotifications() } else { Toast.makeText( context, @@ -127,11 +143,11 @@ class NotificationFragment : BaseFragment(), NotificationView, OnRefreshListener } } - override fun showProgress() { + fun showProgress() { binding.swipeNotificationContainer.isRefreshing = true } - override fun hideProgress() { + fun hideProgress() { binding.swipeNotificationContainer.isRefreshing = false } @@ -140,7 +156,7 @@ class NotificationFragment : BaseFragment(), NotificationView, OnRefreshListener binding.rvNotifications, binding.layoutError.root, ) - presenter?.loadNotifications() + loadNotifications() } override fun onDestroyView() { diff --git a/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt new file mode 100644 index 000000000..de1198cc1 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt @@ -0,0 +1,43 @@ +package org.mifos.mobile.viewModels + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.observers.DisposableObserver +import io.reactivex.schedulers.Schedulers +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.notification.MifosNotification +import javax.inject.Inject + +class NotificationViewModel @Inject constructor(private val dataManager : DataManager?): ViewModel() { + private val compositeDisposables: CompositeDisposable = CompositeDisposable() + + private var loadNotificationsResultSuccess = MutableLiveData() + val readLoadNotificationsResultSuccess : LiveData get() = loadNotificationsResultSuccess + + private var loadedNotifications : List? = null + val readLoadedNotifications : List get() = loadedNotifications!! + + fun loadNotifications() { + dataManager?.notifications + ?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribeOn(Schedulers.io()) + ?.subscribeWith(object : DisposableObserver?>() { + override fun onComplete() {} + override fun onError(e: Throwable) { + loadNotificationsResultSuccess.value = false + } + override fun onNext(notificationModels: List) { + loadedNotifications = notificationModels + loadNotificationsResultSuccess.value = true + } + })?.let { compositeDisposables.add(it) } + } + + override fun onCleared() { + super.onCleared() + compositeDisposables.clear() + } +} diff --git a/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModelFactory.kt b/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModelFactory.kt new file mode 100644 index 000000000..b8d65999a --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModelFactory.kt @@ -0,0 +1,19 @@ +package org.mifos.mobile.viewModels + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.injection.PerActivity +import javax.inject.Inject + +@PerActivity +class NotificationViewModelFactory @Inject constructor(private val dataManager : DataManager?) : + ViewModelProvider.Factory { + + override fun create(modelClass: Class): T { + if (modelClass.isAssignableFrom(NotificationViewModel::class.java)) { + return NotificationViewModel(dataManager) as T + } + throw IllegalArgumentException("Unknown ViewModel class: " + modelClass.name) + } +} From c7c42b6a51bf6ccc46b1f30f6c01ed4452a6c808 Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Fri, 23 Jun 2023 00:44:10 +0530 Subject: [PATCH 05/35] feat : Migrating Notification Fragment to MVVM. --- .../mifos/mobile/NotificationRepository.kt | 12 ++++++++++++ .../ui/fragments/NotificationFragment.kt | 19 ++++++++++++------- .../mifos/mobile/utils/NotificationUiState.kt | 9 +++++++++ .../viewModels/NotificationViewModel.kt | 18 +++++++++--------- 4 files changed, 42 insertions(+), 16 deletions(-) create mode 100644 app/src/main/java/org/mifos/mobile/NotificationRepository.kt create mode 100644 app/src/main/java/org/mifos/mobile/utils/NotificationUiState.kt diff --git a/app/src/main/java/org/mifos/mobile/NotificationRepository.kt b/app/src/main/java/org/mifos/mobile/NotificationRepository.kt new file mode 100644 index 000000000..ae826210d --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/NotificationRepository.kt @@ -0,0 +1,12 @@ +package org.mifos.mobile + +import io.reactivex.Observable +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.notification.MifosNotification + +class NotificationRepository(private val dataManager: DataManager?) { + + fun loadNotifications() : Observable?>? { + return dataManager?.notifications + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt index c08521874..31f7e67c3 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt @@ -10,6 +10,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler import org.mifos.mobile.BuildConfig +import org.mifos.mobile.utils.NotificationUiState import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentNotificationBinding import org.mifos.mobile.models.notification.MifosNotification @@ -108,12 +109,17 @@ class NotificationFragment : BaseFragment(), OnRefreshListener { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - viewModel.readLoadNotificationsResultSuccess.observe(viewLifecycleOwner) { loadNotificationsResultSuccess -> - hideProgress() - if(loadNotificationsResultSuccess == true) { - showNotifications(viewModel.readLoadedNotifications) - } else { - showError(context?.getString(R.string.notification)) + viewModel.notificationUiState.observe(viewLifecycleOwner) { state -> + when(state) { + NotificationUiState.Loading -> showProgress() + NotificationUiState.Error -> { + hideProgress() + showError(context?.getString(R.string.notification)) + } + is NotificationUiState.LoadNotificationsSuccessful -> { + hideProgress() + showNotifications(state.notifications) + } } } @@ -123,7 +129,6 @@ class NotificationFragment : BaseFragment(), OnRefreshListener { } private fun loadNotifications() { - showProgress() viewModel.loadNotifications() } diff --git a/app/src/main/java/org/mifos/mobile/utils/NotificationUiState.kt b/app/src/main/java/org/mifos/mobile/utils/NotificationUiState.kt new file mode 100644 index 000000000..d0a1216ed --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/utils/NotificationUiState.kt @@ -0,0 +1,9 @@ +package org.mifos.mobile.utils + +import org.mifos.mobile.models.notification.MifosNotification + +sealed class NotificationUiState { + object Loading : NotificationUiState() + data class LoadNotificationsSuccessful(val notifications : List) : NotificationUiState() + object Error : NotificationUiState() +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt index de1198cc1..03ee49473 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt @@ -7,6 +7,8 @@ import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers +import org.mifos.mobile.NotificationRepository +import org.mifos.mobile.utils.NotificationUiState import org.mifos.mobile.api.DataManager import org.mifos.mobile.models.notification.MifosNotification import javax.inject.Inject @@ -14,24 +16,22 @@ import javax.inject.Inject class NotificationViewModel @Inject constructor(private val dataManager : DataManager?): ViewModel() { private val compositeDisposables: CompositeDisposable = CompositeDisposable() - private var loadNotificationsResultSuccess = MutableLiveData() - val readLoadNotificationsResultSuccess : LiveData get() = loadNotificationsResultSuccess - - private var loadedNotifications : List? = null - val readLoadedNotifications : List get() = loadedNotifications!! + private val notificationRepository = NotificationRepository(dataManager) + private val _notificationUiState = MutableLiveData() + val notificationUiState : LiveData get() = _notificationUiState fun loadNotifications() { - dataManager?.notifications + _notificationUiState.value = NotificationUiState.Loading + notificationRepository.loadNotifications() ?.observeOn(AndroidSchedulers.mainThread()) ?.subscribeOn(Schedulers.io()) ?.subscribeWith(object : DisposableObserver?>() { override fun onComplete() {} override fun onError(e: Throwable) { - loadNotificationsResultSuccess.value = false + _notificationUiState.value = NotificationUiState.Error } override fun onNext(notificationModels: List) { - loadedNotifications = notificationModels - loadNotificationsResultSuccess.value = true + _notificationUiState.value = NotificationUiState.LoadNotificationsSuccessful(notificationModels) } })?.let { compositeDisposables.add(it) } } From c0f72443f822a10034edfc4b30d769185670ed95 Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Thu, 22 Jun 2023 11:46:37 +0530 Subject: [PATCH 06/35] feat : migration of Registration Fragment to MVVM. --- .../mifos/mobile/RegistrationRepository.kt | 35 +++ .../ui/fragments/RegistrationFragment.kt | 245 ++++++++++-------- .../mifos/mobile/utils/RegistrationUiState.kt | 7 + .../viewModels/RegistrationViewModel.kt | 41 ++- .../main/res/layout/fragment_registration.xml | 2 + 5 files changed, 209 insertions(+), 121 deletions(-) create mode 100644 app/src/main/java/org/mifos/mobile/RegistrationRepository.kt create mode 100644 app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt diff --git a/app/src/main/java/org/mifos/mobile/RegistrationRepository.kt b/app/src/main/java/org/mifos/mobile/RegistrationRepository.kt new file mode 100644 index 000000000..abff69c84 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/RegistrationRepository.kt @@ -0,0 +1,35 @@ +package org.mifos.mobile + +import io.reactivex.Observable +import okhttp3.ResponseBody +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.register.RegisterPayload + +class RegistrationRepository(private var dataManager : DataManager?) { + + fun registerUser(registerPayload: RegisterPayload?) : Observable? { + return dataManager?.registerUser(registerPayload) + } + + fun createRegisterPayload( + accountNumber: String, + authenticationMode: String, + email: String, + firstName: String, + lastName: String, + mobileNumber: String, + password: String, + username: String + ): RegisterPayload { + return RegisterPayload().apply { + this.accountNumber = accountNumber + this.authenticationMode = authenticationMode + this.email = email + this.firstName = firstName + this.lastName = lastName + this.mobileNumber = mobileNumber + this.password = password + this.username = username + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt index d0d4f05e1..879ba5a54 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt @@ -13,12 +13,12 @@ import androidx.lifecycle.ViewModelProvider import com.hbb20.CountryCodePicker import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentRegistrationBinding -import org.mifos.mobile.models.register.RegisterPayload import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.utils.MFErrorParser import org.mifos.mobile.utils.Network import org.mifos.mobile.utils.PasswordStrength +import org.mifos.mobile.utils.RegistrationUiState import org.mifos.mobile.utils.Toaster import org.mifos.mobile.viewModels.RegistrationViewModel import org.mifos.mobile.viewModels.RegistrationViewModelFactory @@ -45,8 +45,6 @@ class RegistrationFragment : BaseFragment() { (activity as BaseActivity?)?.activityComponent?.inject(this) viewModel = ViewModelProvider(this, viewModelFactory)[RegistrationViewModel::class.java] with(binding) { - progressBar.visibility = View.GONE - passwordStrength.visibility = View.GONE etPassword.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int ) {} override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) { @@ -78,14 +76,11 @@ class RegistrationFragment : BaseFragment() { passwordStrength.setTextColor(str.color) val mode = PorterDuff.Mode.SRC_IN progressBar.progressDrawable?.setColorFilter(str.color, mode) - if (str.getText(context) == getString(R.string.password_strength_weak)) { - progressBar.progress = 25 - } else if (str.getText(context) == getString(R.string.password_strength_medium)) { - progressBar.progress = 50 - } else if (str.getText(context) == getString(R.string.password_strength_strong)) { - progressBar.progress = 75 - } else { - progressBar.progress = 100 + when(str.getText(context)) { + getString(R.string.password_strength_weak) -> progressBar.progress = 25 + getString(R.string.password_strength_medium) -> progressBar.progress = 50 + getString(R.string.password_strength_strong) -> progressBar.progress = 75 + else -> progressBar.progress = 100 } } } @@ -93,12 +88,19 @@ class RegistrationFragment : BaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - viewModel.readRegistrationResultSuccess.observe(viewLifecycleOwner) { registrationResultSuccess -> - hideProgress() - if (registrationResultSuccess == true) { - showRegisteredSuccessfully() - } else { - showError(MFErrorParser.errorMessage(viewModel.readExceptionOnRegistration)) + viewModel.registrationUiState.observe(viewLifecycleOwner) { state -> + when(state) { + RegistrationUiState.Loading -> showProgress() + + RegistrationUiState.RegistrationSuccessful -> { + hideProgress() + showRegisteredSuccessfully() + } + + is RegistrationUiState.ErrorOnRegistration -> { + hideProgress() + showError(MFErrorParser.errorMessage(state.exception)) + } } } @@ -113,25 +115,24 @@ class RegistrationFragment : BaseFragment() { val radioButton = rgVerificationMode.checkedRadioButtonId.let { root.findViewById(it) } - val payload = RegisterPayload().apply { - accountNumber = etAccountNumber.text.toString() - authenticationMode = radioButton?.text.toString() - email = etEmail.text.toString() - firstName = etFirstName.text.toString() - lastName = etLastName.text.toString() - mobileNumber = + val accountNumber = etAccountNumber.text.toString() + val authenticationMode = radioButton?.text.toString() + val email = etEmail.text.toString() + val firstName = etFirstName.text.toString() + val lastName = etLastName.text.toString() + val mobileNumber = countryCodePicker.selectedCountryCode.toString() + etPhoneNumber.text.toString() - if (etPassword.text.toString() != etConfirmPassword.text.toString()) { - Toaster.show(root, getString(R.string.error_password_not_match)) - return - } else { - password = etPassword.text.toString() - } - password = etPassword.text.toString() - username = etUsername.text.toString().replace(" ", "") + if (etPassword.text.toString() != etConfirmPassword.text.toString()) { + Toaster.show(root, getString(R.string.error_password_not_match)) + return } + val password = etPassword.text.toString() + val username = etUsername.text.toString().replace(" ", "") + + val payload = viewModel.createRegisterPayload(accountNumber, authenticationMode, email, firstName, + lastName, mobileNumber, password, username) + if (Network.isConnected(context)) { - showProgress() viewModel.registerUser(payload) } else { Toaster.show(root, getString(R.string.no_internet_connection)) @@ -143,82 +144,110 @@ class RegistrationFragment : BaseFragment() { private fun areFieldsValidated(): Boolean { val rootView = binding.root with(binding) { - if (viewModel.isInputFieldBlank(etAccountNumber.text.toString())) { - Toaster.show( - rootView, - getString(R.string.error_validation_blank, getString(R.string.account_number)), - ) - return false - } else if (viewModel.isInputFieldBlank(etUsername.text.toString())) { - Toaster.show( - rootView, - getString(R.string.error_validation_blank, getString(R.string.username)), - ) - return false - } else if (viewModel.isInputLengthInadequate(etUsername.text.toString())) { - Toaster.show(rootView, getString(R.string.error_username_greater_than_six)) - return false - } else if (viewModel.inputHasSpaces(etUsername.text.toString())) { - Toaster.show( - rootView, - getString( - R.string.error_validation_cannot_contain_spaces, - getString(R.string.username), - getString(R.string.not_contain_username), - ), - ) - return false - } else if (viewModel.isInputFieldBlank(etFirstName.text.toString())) { - Toaster.show( - rootView, - getString(R.string.error_validation_blank, getString(R.string.first_name)), - ) - return false - } else if (viewModel.isInputFieldBlank(etLastName.text.toString())) { - Toaster.show( - rootView, - getString(R.string.error_validation_blank, getString(R.string.last_name)), - ) - return false - } else if (viewModel.isInputFieldBlank(etEmail.text.toString())) { - Toaster.show( - rootView, - getString(R.string.error_validation_blank, getString(R.string.email)), - ) - return false - } else if (viewModel.isInputFieldBlank(etPassword.text.toString())) { - Toaster.show( - rootView, - getString(R.string.error_validation_blank, getString(R.string.password)), - ) - return false - } else if (viewModel.hasLeadingTrailingSpaces(etPassword.text.toString())) { - Toaster.show( - rootView, - getString( - R.string.error_validation_cannot_contain_leading_or_trailing_spaces, - getString(R.string.password), - ), - ) - return false - } else if (viewModel.isEmailInvalid(etEmail.text.toString())) { - Toaster.show(rootView, getString(R.string.error_invalid_email)) - return false - } else if (viewModel.isInputLengthInadequate(etPassword.text.toString())) { - Toaster.show( - rootView, - getString( - R.string.error_validation_minimum_chars, - getString(R.string.password), - resources.getInteger(R.integer.password_minimum_length), - ), - ) - return false - } else if (!isPhoneNumberValid(countryCodePicker)) { - Toaster.show(rootView, getString(R.string.invalid_phn_number)) - return false + return when { + viewModel.isInputFieldBlank(etAccountNumber.text.toString()) -> { + Toaster.show( + rootView, + getString( + R.string.error_validation_blank, + getString(R.string.account_number) + ), + ) + false + } + + viewModel.isInputFieldBlank(etUsername.text.toString()) -> { + Toaster.show( + rootView, + getString(R.string.error_validation_blank, getString(R.string.username)), + ) + false + } + + viewModel.isInputLengthInadequate(etUsername.text.toString()) -> { + Toaster.show(rootView, getString(R.string.error_username_greater_than_six)) + false + } + + viewModel.inputHasSpaces(etUsername.text.toString()) -> { + Toaster.show( + rootView, + getString( + R.string.error_validation_cannot_contain_spaces, + getString(R.string.username), + getString(R.string.not_contain_username), + ), + ) + false + } + + viewModel.isInputFieldBlank(etFirstName.text.toString()) -> { + Toaster.show( + rootView, + getString(R.string.error_validation_blank, getString(R.string.first_name)), + ) + false + } + + viewModel.isInputFieldBlank(etLastName.text.toString()) -> { + Toaster.show( + rootView, + getString(R.string.error_validation_blank, getString(R.string.last_name)), + ) + false + } + + viewModel.isInputFieldBlank(etEmail.text.toString()) -> { + Toaster.show( + rootView, + getString(R.string.error_validation_blank, getString(R.string.email)), + ) + false + } + + viewModel.isInputFieldBlank(etPassword.text.toString()) -> { + Toaster.show( + rootView, + getString(R.string.error_validation_blank, getString(R.string.password)), + ) + false + } + + viewModel.hasLeadingTrailingSpaces(etPassword.text.toString()) -> { + Toaster.show( + rootView, + getString( + R.string.error_validation_cannot_contain_leading_or_trailing_spaces, + getString(R.string.password), + ), + ) + false + } + + viewModel.isEmailInvalid(etEmail.text.toString()) -> { + Toaster.show(rootView, getString(R.string.error_invalid_email)) + false + } + + viewModel.isInputLengthInadequate(etPassword.text.toString()) -> { + Toaster.show( + rootView, + getString( + R.string.error_validation_minimum_chars, + getString(R.string.password), + resources.getInteger(R.integer.password_minimum_length), + ), + ) + return false + } + + (!isPhoneNumberValid(countryCodePicker)) -> { + Toaster.show(rootView, getString(R.string.invalid_phn_number)) + return false + } + + else -> true } - return true } } diff --git a/app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt b/app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt new file mode 100644 index 000000000..8f865a3fe --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt @@ -0,0 +1,7 @@ +package org.mifos.mobile.utils + +sealed class RegistrationUiState { + data class ErrorOnRegistration(val exception : Throwable) : RegistrationUiState() + object RegistrationSuccessful : RegistrationUiState() + object Loading : RegistrationUiState() +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt index b00fae478..71cc01a28 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt @@ -9,51 +9,66 @@ import io.reactivex.disposables.CompositeDisposable import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody +import org.mifos.mobile.RegistrationRepository import org.mifos.mobile.api.DataManager import org.mifos.mobile.models.register.RegisterPayload +import org.mifos.mobile.utils.RegistrationUiState import javax.inject.Inject class RegistrationViewModel @Inject constructor(var dataManager : DataManager?) : ViewModel() { private val compositeDisposables: CompositeDisposable = CompositeDisposable() - private var registrationResultSuccess = MutableLiveData() - val readRegistrationResultSuccess : LiveData get() = registrationResultSuccess - private var exceptionOnRegistration : Throwable? = null - val readExceptionOnRegistration : Throwable get() = exceptionOnRegistration!! + private val registrationRepository = RegistrationRepository(dataManager) + private val _registrationUiState = MutableLiveData() + val registrationUiState : LiveData get() = _registrationUiState fun isInputFieldBlank(fieldText : String) : Boolean { - return fieldText.trim { it <= ' '}.isEmpty() + return fieldText.trim().isEmpty() } fun isInputLengthInadequate(fieldText : String) : Boolean { - return fieldText.trim { it <= ' '}.length < 6 + return fieldText.trim().length < 6 } fun inputHasSpaces(fieldText: String) : Boolean { - return fieldText.trim { it <= ' '}.contains(" ") + return fieldText.trim().contains(" ") } fun hasLeadingTrailingSpaces(fieldText: String) : Boolean { - return fieldText.trim { it <= ' ' }.length < fieldText.length + return fieldText.trim().length < fieldText.length } fun isEmailInvalid(emailText : String) : Boolean { - return !Patterns.EMAIL_ADDRESS.matcher(emailText.trim { it <= ' ' }).matches() + return !Patterns.EMAIL_ADDRESS.matcher(emailText.trim()).matches() + } + + fun createRegisterPayload( + accountNumber: String, + authenticationMode: String, + email: String, + firstName: String, + lastName: String, + mobileNumber: String, + password: String, + username: String + ) : RegisterPayload { + return registrationRepository.createRegisterPayload(accountNumber, authenticationMode, email, firstName, + lastName, mobileNumber, password, username) } fun registerUser(registerPayload: RegisterPayload?) { - dataManager?.registerUser(registerPayload) + _registrationUiState.value = RegistrationUiState.Loading + registrationRepository.registerUser(registerPayload) ?.observeOn(AndroidSchedulers.mainThread()) ?.subscribeOn(Schedulers.io()) ?.subscribeWith(object : DisposableObserver() { override fun onComplete() {} override fun onError(e: Throwable) { - exceptionOnRegistration = e - registrationResultSuccess.value = false + _registrationUiState.value = RegistrationUiState.ErrorOnRegistration(e) } override fun onNext(responseBody: ResponseBody) { - registrationResultSuccess.value = true + _registrationUiState.value = RegistrationUiState.RegistrationSuccessful } })?.let { compositeDisposables.add(it) } } diff --git a/app/src/main/res/layout/fragment_registration.xml b/app/src/main/res/layout/fragment_registration.xml index 95b73b8df..feb1019c2 100644 --- a/app/src/main/res/layout/fragment_registration.xml +++ b/app/src/main/res/layout/fragment_registration.xml @@ -129,6 +129,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" + android:visibility="gone" android:indeterminate="false" android:progress="0" /> @@ -137,6 +138,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="@dimen/Mifos.DesignSystem.Spacing.marginWords" + android:visibility="gone" android:gravity="center_horizontal" android:text="@string/password_strength_weak" /> From e5af918ab2eeb661d01953f75abed0b89e6c3cee Mon Sep 17 00:00:00 2001 From: Pratyush Singh Date: Fri, 30 Jun 2023 01:16:21 +0530 Subject: [PATCH 07/35] feat: hilt dependencies in the project --- app/build.gradle | 10 ++++++++++ .../main/java/org/mifos/mobile/MifosSelfServiceApp.kt | 7 ++++--- .../mobile/injection/component/ActivityComponent.kt | 5 +++++ .../mifos/mobile/injection/module/ActivityModule.kt | 9 ++++++--- .../mifos/mobile/injection/module/ApplicationModule.kt | 9 ++++++--- .../org/mifos/mobile/ui/activities/HomeActivity.kt | 2 +- .../org/mifos/mobile/ui/activities/LoginActivity.kt | 2 +- .../org/mifos/mobile/ui/activities/SplashActivity.kt | 3 ++- .../mobile/ui/fragments/AccountOverviewFragment.kt | 2 +- .../org/mifos/mobile/ui/fragments/AccountsFragment.kt | 2 +- .../mifos/mobile/ui/fragments/AddGuarantorFragment.kt | 2 +- .../ui/fragments/BeneficiaryAddOptionsFragment.kt | 2 +- .../ui/fragments/BeneficiaryApplicationFragment.kt | 2 +- .../mobile/ui/fragments/BeneficiaryDetailFragment.kt | 2 +- .../mobile/ui/fragments/BeneficiaryListFragment.kt | 2 +- .../mobile/ui/fragments/ClientAccountsFragment.kt | 2 +- .../mifos/mobile/ui/fragments/ClientChargeFragment.kt | 2 +- .../mobile/ui/fragments/GuarantorDetailFragment.kt | 2 +- .../mifos/mobile/ui/fragments/GuarantorListFragment.kt | 2 +- .../java/org/mifos/mobile/ui/fragments/HelpFragment.kt | 2 +- .../java/org/mifos/mobile/ui/fragments/HomeFragment.kt | 2 +- .../org/mifos/mobile/ui/fragments/HomeOldFragment.kt | 2 +- .../mobile/ui/fragments/LoanAccountSummaryFragment.kt | 2 +- .../ui/fragments/LoanAccountTransactionFragment.kt | 2 +- .../mobile/ui/fragments/LoanAccountWithdrawFragment.kt | 2 +- .../mobile/ui/fragments/LoanAccountsDetailFragment.kt | 2 +- .../mobile/ui/fragments/LoanApplicationFragment.kt | 2 +- .../ui/fragments/LoanRepaymentScheduleFragment.kt | 2 +- .../mifos/mobile/ui/fragments/NotificationFragment.kt | 2 +- .../mifos/mobile/ui/fragments/QrCodeImportFragment.kt | 2 +- .../mifos/mobile/ui/fragments/QrCodeReaderFragment.kt | 2 +- .../mobile/ui/fragments/RecentTransactionsFragment.kt | 2 +- .../mifos/mobile/ui/fragments/RegistrationFragment.kt | 2 +- .../ui/fragments/RegistrationVerificationFragment.kt | 2 +- .../ui/fragments/ReviewLoanApplicationFragment.kt | 6 +----- .../ui/fragments/SavingAccountsDetailFragment.kt | 2 +- .../ui/fragments/SavingAccountsTransactionFragment.kt | 2 +- .../ui/fragments/SavingsAccountApplicationFragment.kt | 2 +- .../ui/fragments/SavingsAccountWithdrawFragment.kt | 2 +- .../mobile/ui/fragments/SavingsMakeTransferFragment.kt | 2 +- .../mobile/ui/fragments/ThirdPartyTransferFragment.kt | 2 +- .../mobile/ui/fragments/TransferProcessFragment.kt | 2 +- .../mobile/ui/fragments/UpdatePasswordFragment.kt | 2 +- .../mifos/mobile/ui/fragments/UserProfileFragment.kt | 2 +- .../viewModels/ReviewLoanApplicationViewModel.kt | 2 ++ build.gradle | 4 +++- 46 files changed, 76 insertions(+), 53 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 780cee0af..405147247 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,6 +4,7 @@ apply plugin: 'com.google.android.gms.oss-licenses-plugin' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' +apply plugin: 'com.google.dagger.hilt.android' apply from: '../config/quality/quality.gradle' @@ -19,6 +20,7 @@ android { // A test runner provided by https://code.google.com/p/android-test-kit/ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true + javaCompileOptions.annotationProcessorOptions.arguments['dagger.hilt.disableModulesHaveInstallInCheck'] = 'true' ndk { abiFilters "armeabi-v7a", "x86", "x86_64", "arm64-v8a" @@ -80,6 +82,10 @@ android { buildFeatures { viewBinding = true } + + kapt { + correctErrorTypes = true + } } dependencies { @@ -179,5 +185,9 @@ dependencies { implementation 'com.github.rahul-gill.mifos-ui-library:uihouse:alpha-2.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' + // Hilt + implementation("com.google.dagger:hilt-android:2.44") + kapt("com.google.dagger:hilt-android-compiler:2.44") + } apply plugin: 'com.google.gms.google-services' diff --git a/app/src/main/java/org/mifos/mobile/MifosSelfServiceApp.kt b/app/src/main/java/org/mifos/mobile/MifosSelfServiceApp.kt index b6f1e6168..326d7528e 100644 --- a/app/src/main/java/org/mifos/mobile/MifosSelfServiceApp.kt +++ b/app/src/main/java/org/mifos/mobile/MifosSelfServiceApp.kt @@ -8,6 +8,8 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics import com.mifos.mobile.passcode.utils.ForegroundChecker import com.raizlabs.android.dbflow.config.FlowConfig import com.raizlabs.android.dbflow.config.FlowManager +import dagger.hilt.android.EntryPointAccessors +import dagger.hilt.android.HiltAndroidApp import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.injection.component.ApplicationComponent import org.mifos.mobile.injection.component.DaggerApplicationComponent @@ -20,6 +22,7 @@ import java.util.Locale * @author ishan * @since 08/07/16 */ +@HiltAndroidApp class MifosSelfServiceApp : MultiDexApplication() { private var applicationComponent: ApplicationComponent? = null @@ -53,9 +56,7 @@ class MifosSelfServiceApp : MultiDexApplication() { fun component(): ApplicationComponent? { if (applicationComponent == null) { - applicationComponent = DaggerApplicationComponent.builder() - .applicationModule(ApplicationModule(this)) - .build() + applicationComponent = EntryPointAccessors.fromApplication(this, ApplicationComponent::class.java) } return applicationComponent } diff --git a/app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt b/app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt index 5fb96e011..e2053fe2f 100644 --- a/app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt +++ b/app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt @@ -1,6 +1,9 @@ package org.mifos.mobile.injection.component import dagger.Component +import dagger.hilt.EntryPoint +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent import org.mifos.mobile.injection.PerActivity import org.mifos.mobile.injection.module.ActivityModule import org.mifos.mobile.ui.activities.HomeActivity @@ -49,6 +52,8 @@ import org.mifos.mobile.ui.fragments.UserProfileFragment * @since 08/07/16 */ @PerActivity +@InstallIn(SingletonComponent::class) +@EntryPoint @Component(dependencies = [ApplicationComponent::class], modules = [ActivityModule::class]) interface ActivityComponent { fun inject(loginActivity: LoginActivity?) diff --git a/app/src/main/java/org/mifos/mobile/injection/module/ActivityModule.kt b/app/src/main/java/org/mifos/mobile/injection/module/ActivityModule.kt index 9d574c14e..6ae26e1fb 100644 --- a/app/src/main/java/org/mifos/mobile/injection/module/ActivityModule.kt +++ b/app/src/main/java/org/mifos/mobile/injection/module/ActivityModule.kt @@ -4,6 +4,8 @@ import android.app.Activity import android.content.Context import dagger.Module import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent import org.mifos.mobile.injection.ActivityContext /** @@ -11,15 +13,16 @@ import org.mifos.mobile.injection.ActivityContext * @since 08/07/16 */ @Module -class ActivityModule(private val activity: Activity) { +@InstallIn(SingletonComponent::class) +class ActivityModule(private val activity: Activity? = null) { @Provides fun providesActivity(): Activity { - return activity + return activity!! } @Provides @ActivityContext fun providesContext(): Context { - return activity + return activity!! } } diff --git a/app/src/main/java/org/mifos/mobile/injection/module/ApplicationModule.kt b/app/src/main/java/org/mifos/mobile/injection/module/ApplicationModule.kt index 97099e825..96042c3c8 100644 --- a/app/src/main/java/org/mifos/mobile/injection/module/ApplicationModule.kt +++ b/app/src/main/java/org/mifos/mobile/injection/module/ApplicationModule.kt @@ -4,6 +4,8 @@ import android.app.Application import android.content.Context import dagger.Module import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent import org.mifos.mobile.api.BaseApiManager import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.injection.ApplicationContext @@ -14,16 +16,17 @@ import javax.inject.Singleton * @since 08/07/16 */ @Module -class ApplicationModule(private val application: Application) { +@InstallIn(SingletonComponent::class) +class ApplicationModule(private val application: Application? = null) { @Provides fun provideApplication(): Application { - return application + return application!! } @Provides @ApplicationContext fun provideContext(): Context { - return application + return application!! } @Provides diff --git a/app/src/main/java/org/mifos/mobile/ui/activities/HomeActivity.kt b/app/src/main/java/org/mifos/mobile/ui/activities/HomeActivity.kt index a6d7f72a3..299d9b09d 100644 --- a/app/src/main/java/org/mifos/mobile/ui/activities/HomeActivity.kt +++ b/app/src/main/java/org/mifos/mobile/ui/activities/HomeActivity.kt @@ -78,7 +78,7 @@ class HomeActivity : public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityHomeBinding.inflate(layoutInflater) - activityComponent?.inject(this) + //activityComponent?.inject(this) setContentView(binding.root) clientId = preferencesHelper?.clientId setupNavigationBar() diff --git a/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt b/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt index 735436305..f8c665369 100644 --- a/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt +++ b/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt @@ -32,7 +32,7 @@ class LoginActivity : BaseActivity(), LoginView { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityLoginBinding.inflate(layoutInflater) - activityComponent?.inject(this) + //activityComponent?.inject(this) setContentView(binding.root) loginPresenter?.attachView(this) dismissSoftKeyboardOnBkgTap(binding.nsvBackground) diff --git a/app/src/main/java/org/mifos/mobile/ui/activities/SplashActivity.kt b/app/src/main/java/org/mifos/mobile/ui/activities/SplashActivity.kt index d5143528c..7117c87e4 100644 --- a/app/src/main/java/org/mifos/mobile/ui/activities/SplashActivity.kt +++ b/app/src/main/java/org/mifos/mobile/ui/activities/SplashActivity.kt @@ -3,6 +3,7 @@ package org.mifos.mobile.ui.activities import android.content.Intent import android.os.Bundle import com.mifos.mobile.passcode.utils.PasscodePreferencesHelper +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.utils.Constants @@ -16,7 +17,7 @@ class SplashActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { val intent: Intent? super.onCreate(savedInstanceState) - activityComponent?.inject(this) + //activityComponent?.inject(this) passcodePreferencesHelper = PasscodePreferencesHelper(this) if (passcodePreferencesHelper?.passCode?.isNotEmpty() == true) { intent = Intent(this, PassCodeActivity::class.java) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/AccountOverviewFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/AccountOverviewFragment.kt index 15b7d1384..b8894694f 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/AccountOverviewFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/AccountOverviewFragment.kt @@ -45,7 +45,7 @@ class AccountOverviewFragment : BaseFragment(), AccountOverviewMvpView, OnRefres savedInstanceState: Bundle?, ): View { _binding = FragmentAccountOverviewBinding.inflate(inflater, container, false) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) accountOverviewPresenter?.attachView(this) setToolbarTitle(getString(R.string.accounts_overview)) binding.swipeContainer.setColorSchemeResources( diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/AccountsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/AccountsFragment.kt index 1d71d9043..608f0eadd 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/AccountsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/AccountsFragment.kt @@ -76,7 +76,7 @@ class AccountsFragment : BaseFragment(), OnRefreshListener, AccountsView { private var sweetUIErrorHandler: SweetUIErrorHandler? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) loanAccounts = ArrayList() savingAccounts = ArrayList() shareAccounts = ArrayList() diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/AddGuarantorFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/AddGuarantorFragment.kt index 808b90423..aea7859cb 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/AddGuarantorFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/AddGuarantorFragment.kt @@ -59,7 +59,7 @@ class AddGuarantorFragment : BaseFragment(), AddGuarantorView { savedInstanceState: Bundle?, ): View { _binding = FragmentAddGuarantorBinding.inflate(inflater, container, false) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) if (guarantorState == GuarantorState.CREATE) { setToolbarTitle(getString(R.string.add_guarantor)) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryAddOptionsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryAddOptionsFragment.kt index e11ef3025..22146453d 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryAddOptionsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryAddOptionsFragment.kt @@ -37,7 +37,7 @@ class BeneficiaryAddOptionsFragment : BaseFragment() { ): View { _binding = FragmentBeneficiaryAddOptionsBinding.inflate(inflater, container, false) setToolbarTitle(getString(R.string.add_beneficiary)) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) return binding.root } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryApplicationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryApplicationFragment.kt index 030c4e521..63264bb61 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryApplicationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryApplicationFragment.kt @@ -69,7 +69,7 @@ class BeneficiaryApplicationFragment : BaseFragment(), BeneficiaryApplicationVie savedInstanceState: Bundle?, ): View { _binding = FragmentBeneficiaryApplicationBinding.inflate(inflater, container, false) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) sweetUIErrorHandler = SweetUIErrorHandler(activity, binding.root) showUserInterface() presenter?.attachView(this) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryDetailFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryDetailFragment.kt index e53efbc0f..594e2ac75 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryDetailFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryDetailFragment.kt @@ -48,7 +48,7 @@ class BeneficiaryDetailFragment : BaseFragment(), BeneficiaryDetailView { savedInstanceState: Bundle?, ): View { _binding = FragmentBeneficiaryDetailBinding.inflate(inflater, container, false) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.beneficiary_detail)) presenter?.attachView(this) showUserInterface() diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryListFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryListFragment.kt index f32177c66..8322866dc 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryListFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryListFragment.kt @@ -48,7 +48,7 @@ class BeneficiaryListFragment : BaseFragment(), OnRefreshListener, Beneficiaries ): View { _binding = FragmentBeneficiaryListBinding.inflate(inflater, container, false) beneficiaryListAdapter = BeneficiaryListAdapter(::onItemClick) - (activity as BaseActivity?)?.activityComponent?.inject(this) + ////(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.beneficiaries)) sweetUIErrorHandler = SweetUIErrorHandler(activity, binding.root) showUserInterface() diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/ClientAccountsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/ClientAccountsFragment.kt index 5ccb6d085..a4cf3774f 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/ClientAccountsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/ClientAccountsFragment.kt @@ -71,7 +71,7 @@ import javax.inject.Inject ): View { _binding = FragmentClientAccountsBinding.inflate(inflater, container, false) val rootView = binding.root - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) accountsPresenter?.attachView(this) setToolbarTitle(getString(R.string.accounts)) setUpViewPagerAndTabLayout() diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/ClientChargeFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/ClientChargeFragment.kt index b3f852bfb..f12175318 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/ClientChargeFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/ClientChargeFragment.kt @@ -58,7 +58,7 @@ class ClientChargeFragment : BaseFragment(), ClientChargeView { private var sweetUIErrorHandler: SweetUIErrorHandler? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) if (arguments != null) { id = arguments?.getLong(Constants.CLIENT_ID) chargeType = arguments?.getSerializable(Constants.CHARGE_TYPE) as ChargeType diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorDetailFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorDetailFragment.kt index 4d7704492..37e8f6a8a 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorDetailFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorDetailFragment.kt @@ -61,7 +61,7 @@ import javax.inject.Inject _binding = FragmentGuarantorDetailBinding.inflate(inflater, container, false) setToolbarTitle(getString(R.string.guarantor_details)) setHasOptionsMenu(true) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) if (isFirstTime) { isFirstTime = false setUpRxBus() diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorListFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorListFragment.kt index ccaed0a8e..ad7d878cc 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorListFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorListFragment.kt @@ -52,7 +52,7 @@ class GuarantorListFragment : BaseFragment(), GuarantorListView { ): View { _binding = FragmentGuarantorListBinding.inflate(inflater, container, false) setToolbarTitle(getString(R.string.view_guarantor)) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) if (list == null) { presenter?.getGuarantorList(loanId) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/HelpFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/HelpFragment.kt index aba6175e0..057d77df2 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/HelpFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/HelpFragment.kt @@ -53,7 +53,7 @@ class HelpFragment : BaseFragment(), HelpView { _binding = FragmentHelpBinding.inflate(inflater, container, false) val rootView = binding.root setHasOptionsMenu(true) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) setToolbarTitle(getString(R.string.help)) sweetUIErrorHandler = SweetUIErrorHandler(activity, rootView) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/HomeFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/HomeFragment.kt index 65cbdaf9c..86606396e 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/HomeFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/HomeFragment.kt @@ -71,7 +71,7 @@ class HomeFragment : BaseFragment(), HomeView, OnRefreshListener { savedInstanceState: Bundle?, ): View { rootView = inflater.inflate(R.layout.fragment_home_ui, container, false) - (activity as HomeActivity?)?.activityComponent?.inject(this) +// (activity as HomeActivity?)?.activityComponent?.inject(this) ButterKnife.bind(this, rootView) clientId = preferencesHelper?.clientId setHasOptionsMenu(true) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt index 48a746912..0914f2d2c 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt @@ -72,7 +72,7 @@ class HomeOldFragment : BaseFragment(), HomeOldView, OnRefreshListener { ): View { _binding = FragmentHomeOldBinding.inflate(inflater, container, false) val rootView = binding.root - (activity as HomeActivity?)?.activityComponent?.inject(this) +// (activity as HomeActivity?)?.activityComponent?.inject(this) clientId = preferencesHelper?.clientId presenter?.attachView(this) setHasOptionsMenu(true) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountSummaryFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountSummaryFragment.kt index 2fdbaef51..a1ca4a0f9 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountSummaryFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountSummaryFragment.kt @@ -24,7 +24,7 @@ class LoanAccountSummaryFragment : BaseFragment() { private var loanWithAssociations: LoanWithAssociations? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) if (arguments != null) { loanWithAssociations = arguments?.getParcelable(Constants.LOAN_ACCOUNT) } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt index e98a76ee6..08c53973b 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt @@ -44,7 +44,7 @@ class LoanAccountTransactionFragment : BaseFragment(), LoanAccountsTransactionVi private var sweetUIErrorHandler: SweetUIErrorHandler? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) if (arguments != null) { loanId = arguments?.getLong(Constants.LOAN_ID) } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt index bfcfd367b..d5d744f29 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt @@ -31,7 +31,7 @@ class LoanAccountWithdrawFragment : BaseFragment(), LoanAccountWithdrawView { private var loanWithAssociations: LoanWithAssociations? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) if (arguments != null) { loanWithAssociations = arguments?.getParcelable(Constants.LOAN_ACCOUNT) } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt index d7c2c2591..0a3fe68d7 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt @@ -63,7 +63,7 @@ class LoanAccountsDetailFragment : BaseFragment(), LoanAccountsDetailView { container: ViewGroup?, savedInstanceState: Bundle?, ): View { - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) _binding = FragmentLoanAccountDetailsBinding.inflate(inflater, container, false) val rootView = binding.root setToolbarTitle(getString(R.string.loan_account_details)) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt index 42f80e048..9dfebadf2 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt @@ -99,7 +99,7 @@ class LoanApplicationFragment : BaseFragment(), LoanApplicationMvpView { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) if (arguments != null) { loanState = arguments?.getSerializable(Constants.LOAN_STATE) as LoanState if (loanState == LoanState.CREATE) { diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt index 656c413cf..f022482cf 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt @@ -45,7 +45,7 @@ class LoanRepaymentScheduleFragment : BaseFragment(), LoanRepaymentScheduleMvpVi private var loanWithAssociations: LoanWithAssociations? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.loan_repayment_schedule)) if (arguments != null) loanId = arguments?.getLong(Constants.LOAN_ID) } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt index 490cb028b..de771aa65 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt @@ -39,7 +39,7 @@ class NotificationFragment : BaseFragment(), NotificationView, OnRefreshListener override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setToolbarTitle(getString(R.string.notification)) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) } override fun onCreateView( diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeImportFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeImportFragment.kt index 467517365..8b479f0d4 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeImportFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeImportFragment.kt @@ -58,7 +58,7 @@ class QrCodeImportFragment : BaseFragment(), QrCodeImportView { savedInstanceState: Bundle?, ): View { _binding = FragmentQrCodeImportBinding.inflate(inflater, container, false) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.import_qr)) // load the uri setBitmapImage(qrUri) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeReaderFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeReaderFragment.kt index 07a1fc509..1682f2308 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeReaderFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeReaderFragment.kt @@ -35,7 +35,7 @@ class QrCodeReaderFragment : BaseFragment(), ResultHandler { ): View { _binding = FragmentScanQrCodeBinding.inflate(inflater, container, false) setToolbarTitle(getString(R.string.add_beneficiary)) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) binding.viewScanner.setAutoFocus(true) binding.btnFlash.setOnClickListener { turnOnFlash() diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt index 46a0dac0d..e69dc17b3 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt @@ -45,7 +45,7 @@ class RecentTransactionsFragment : BaseFragment(), RecentTransactionsView, OnRef private var recentTransactionList: MutableList? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) recentTransactionList = ArrayList() } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt index 4a15701b2..45eb787d1 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt @@ -40,7 +40,7 @@ class RegistrationFragment : BaseFragment(), RegistrationView { ): View { _binding = FragmentRegistrationBinding.inflate(inflater, container, false) val rootView = binding.root - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) binding.progressBar.visibility = View.GONE binding.passwordStrength.visibility = View.GONE diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt index 7962982b9..dec12f98a 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt @@ -34,7 +34,7 @@ class RegistrationVerificationFragment : BaseFragment(), RegistrationVerificatio ): View { _binding = FragmentRegistrationVerificationBinding.inflate(inflater, container, false) val rootView = binding.root - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) return rootView } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt index d84864e51..24d136a78 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt @@ -31,8 +31,6 @@ import org.mifos.mobile.utils.MFErrorParser import org.mifos.mobile.utils.Network import org.mifos.mobile.utils.Toaster import org.mifos.mobile.viewModels.ReviewLoanApplicationViewModel -import org.mifos.mobile.viewModels.ReviewLoanApplicationViewModelFactory -import javax.inject.Inject class ReviewLoanApplicationFragment : BaseFragment() { @@ -80,8 +78,6 @@ class ReviewLoanApplicationFragment : BaseFragment() { } } - @Inject - lateinit var viewModelFactory: ReviewLoanApplicationViewModelFactory lateinit var rootView: View @@ -94,7 +90,7 @@ class ReviewLoanApplicationFragment : BaseFragment() { ): View { rootView = inflater.inflate(R.layout.fragment_review_loan_application, container, false) (activity as BaseActivity).activityComponent?.inject(this) - viewModel = ViewModelProviders.of(this, viewModelFactory) + viewModel = ViewModelProviders.of(this) .get(ReviewLoanApplicationViewModel::class.java) val loanState = arguments?.getSerializable(LOAN_STATE) as LoanState if (loanState == LoanState.CREATE) { diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt index 81c6fdac6..9c5940643 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt @@ -68,7 +68,7 @@ class SavingAccountsDetailFragment : BaseFragment(), SavingAccountsDetailView { savedInstanceState: Bundle?, ): View { _binding = FragmentSavingAccountDetailsBinding.inflate(inflater, container, false) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.saving_account_details)) savingAccountsDetailPresenter?.attachView(this) sweetUIErrorHandler = SweetUIErrorHandler(context, binding.root) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt index 93d51dd67..ed15c16ac 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt @@ -76,7 +76,7 @@ class SavingAccountsTransactionFragment : BaseFragment(), SavingAccountsTransact override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.saving_account_transactions_details)) if (arguments != null) savingsId = arguments?.getLong(Constants.SAVINGS_ID)!! } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountApplicationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountApplicationFragment.kt index b5b1fcd48..c54a11671 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountApplicationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountApplicationFragment.kt @@ -59,7 +59,7 @@ class SavingsAccountApplicationFragment : BaseFragment(), SavingsAccountApplicat savedInstanceState: Bundle?, ): View { _binding = FragmentSavingsAccountApplicationBinding.inflate(inflater) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) presenter?.loadSavingsAccountApplicationTemplate(preferencesHelper?.clientId, state) return binding.root diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountWithdrawFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountWithdrawFragment.kt index d46e5ef22..510281dfb 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountWithdrawFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountWithdrawFragment.kt @@ -43,7 +43,7 @@ class SavingsAccountWithdrawFragment : BaseFragment(), SavingsAccountWithdrawVie savedInstanceState: Bundle?, ): View { _binding = FragmentSavingsAccountWithdrawFragmentBinding.inflate(inflater, container, false) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) showUserInterface() return binding.root diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsMakeTransferFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsMakeTransferFragment.kt index c7e6aebd5..c4bafec92 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsMakeTransferFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsMakeTransferFragment.kt @@ -72,7 +72,7 @@ class SavingsMakeTransferFragment : BaseFragment(), SavingsMakeTransferMvpView { savedInstanceState: Bundle?, ): View { _binding = FragmentSavingsMakeTransferBinding.inflate(inflater, container, false) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.transfer)) savingsMakeTransferPresenter?.attachView(this) sweetUIErrorHandler = SweetUIErrorHandler(activity, binding.root) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/ThirdPartyTransferFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/ThirdPartyTransferFragment.kt index 61ff095a6..19a5e269e 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/ThirdPartyTransferFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/ThirdPartyTransferFragment.kt @@ -67,7 +67,7 @@ class ThirdPartyTransferFragment : BaseFragment(), ThirdPartyTransferView, OnIte container: ViewGroup?, savedInstanceState: Bundle?, ): View { - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) _binding = FragmentThirdPartyTransferBinding.inflate(inflater, container, false) setToolbarTitle(getString(R.string.third_party_transfer)) sweetUIErrorHandler = SweetUIErrorHandler(activity, binding.root) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/TransferProcessFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/TransferProcessFragment.kt index a85aeba4e..be4e255a3 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/TransferProcessFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/TransferProcessFragment.kt @@ -47,7 +47,7 @@ class TransferProcessFragment : BaseFragment(), TransferProcessView { savedInstanceState: Bundle?, ): View { _binding = FragmentTransferProcessBinding.inflate(inflater, container, false) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.transfer)) presenter?.attachView(this) binding.tvAmount.text = CurrencyUtil.formatCurrency(activity, payload?.transferAmount) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt index 5dfd92ecb..05f5706b8 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt @@ -49,7 +49,7 @@ import javax.inject.Inject ): View { _binding = FragmentUpdatePasswordBinding.inflate(inflater, container, false) setToolbarTitle(getString(R.string.change_password)) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) binding.tilNewPassword.editText?.addTextChangedListener(this) binding.tilConfirmNewPassword.editText?.addTextChangedListener(this) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/UserProfileFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/UserProfileFragment.kt index ba7803189..63e86a38e 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/UserProfileFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/UserProfileFragment.kt @@ -48,7 +48,7 @@ class UserProfileFragment : BaseFragment(), UserDetailsView { savedInstanceState: Bundle?, ): View { _binding = FragmentUserProfileBinding.inflate(inflater, container, false) - (activity as BaseActivity?)?.activityComponent?.inject(this) + //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) (activity as BaseActivity?)?.setSupportActionBar(binding.toolbar) // check this part before pushing (activity as BaseActivity?)?.supportActionBar?.setDisplayHomeAsUpEnabled(true) diff --git a/app/src/main/java/org/mifos/mobile/viewModels/ReviewLoanApplicationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/ReviewLoanApplicationViewModel.kt index 6f390e889..4cf9e8fea 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/ReviewLoanApplicationViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/ReviewLoanApplicationViewModel.kt @@ -1,6 +1,7 @@ package org.mifos.mobile.viewModels import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel import io.reactivex.Observable import okhttp3.ResponseBody import org.mifos.mobile.api.DataManager @@ -8,6 +9,7 @@ import org.mifos.mobile.models.payload.LoansPayload import org.mifos.mobile.ui.enums.LoanState import javax.inject.Inject +@HiltViewModel class ReviewLoanApplicationViewModel @Inject constructor(var dataManager: DataManager?) : ViewModel() { diff --git a/build.gradle b/build.gradle index aa36c6c1c..314ba7da8 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,9 @@ buildscript { // in the individual module build.gradle filesa } } - +plugins { + id("com.google.dagger.hilt.android") version "2.44" apply false +} allprojects { repositories { google() From 7174c46d6b27092aba914f8efff6a818a6f5eced Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Wed, 28 Jun 2023 13:17:59 +0530 Subject: [PATCH 08/35] feat : registration fragment migration to MVVM 1. added unit tests for registrationViewModel. 2. added unit tests for userAuthRepository --- app/build.gradle | 1 + .../mobile/repositories/UserAuthRepository.kt | 11 ++ .../UserAuthRepositoryImp.kt} | 28 ++-- .../ui/fragments/RegistrationFragment.kt | 6 +- .../viewModels/RegistrationViewModel.kt | 32 ++-- .../RegistrationViewModelFactory.kt | 6 +- .../repositories/UserAuthRepositoryImpTest.kt | 80 ++++++++++ .../viewModels/RegistrationViewModelTest.kt | 148 ++++++++++++++++++ build.gradle | 2 +- 9 files changed, 266 insertions(+), 48 deletions(-) create mode 100644 app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt rename app/src/main/java/org/mifos/mobile/{RegistrationRepository.kt => repositories/UserAuthRepositoryImp.kt} (52%) create mode 100644 app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt create mode 100644 app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt diff --git a/app/build.gradle b/app/build.gradle index d808e8ae6..367dd74e9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -162,6 +162,7 @@ dependencies { androidTestImplementation "org.mockito:mockito-core:$rootProject.mockitoVersion" androidTestImplementation "org.mockito:mockito-android:$rootProject.mockitoVersion" androidTestImplementation "androidx.annotation:annotation:1.0.0" + implementation "androidx.arch.core:core-testing:$rootProject.archCoreVersion" androidTestImplementation("androidx.test.espresso:espresso-contrib:$rootProject.espressoVersion") { exclude group: 'com.android.support', module: 'appcompat' exclude group: 'com.android.support', module: 'support-v4' diff --git a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt new file mode 100644 index 000000000..b052f330c --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt @@ -0,0 +1,11 @@ +package org.mifos.mobile.repositories + +import io.reactivex.Observable +import okhttp3.ResponseBody + +interface UserAuthRepository { + + fun registerUser(accountNumber: String?, authenticationMode: String?, email: String?, + firstName: String?, lastName: String?, mobileNumber: String?, password: String?, username: String?) + : Observable? +} diff --git a/app/src/main/java/org/mifos/mobile/RegistrationRepository.kt b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt similarity index 52% rename from app/src/main/java/org/mifos/mobile/RegistrationRepository.kt rename to app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt index abff69c84..ed93e240f 100644 --- a/app/src/main/java/org/mifos/mobile/RegistrationRepository.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt @@ -1,27 +1,20 @@ -package org.mifos.mobile +package org.mifos.mobile.repositories import io.reactivex.Observable import okhttp3.ResponseBody import org.mifos.mobile.api.DataManager import org.mifos.mobile.models.register.RegisterPayload +import javax.inject.Inject -class RegistrationRepository(private var dataManager : DataManager?) { +class UserAuthRepositoryImp @Inject constructor(private var dataManager : DataManager?) : + UserAuthRepository { - fun registerUser(registerPayload: RegisterPayload?) : Observable? { - return dataManager?.registerUser(registerPayload) - } - - fun createRegisterPayload( - accountNumber: String, - authenticationMode: String, - email: String, - firstName: String, - lastName: String, - mobileNumber: String, - password: String, - username: String - ): RegisterPayload { - return RegisterPayload().apply { + override fun registerUser( + accountNumber: String?, authenticationMode: String?, email: String?, + firstName: String?, lastName: String?, mobileNumber: String?, password: String?, + username: String? + ) : Observable? { + val registerPayload = RegisterPayload().apply { this.accountNumber = accountNumber this.authenticationMode = authenticationMode this.email = email @@ -31,5 +24,6 @@ class RegistrationRepository(private var dataManager : DataManager?) { this.password = password this.username = username } + return dataManager?.registerUser(registerPayload) } } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt index 879ba5a54..caedf7d53 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt @@ -129,11 +129,9 @@ class RegistrationFragment : BaseFragment() { val password = etPassword.text.toString() val username = etUsername.text.toString().replace(" ", "") - val payload = viewModel.createRegisterPayload(accountNumber, authenticationMode, email, firstName, - lastName, mobileNumber, password, username) - if (Network.isConnected(context)) { - viewModel.registerUser(payload) + viewModel.registerUser(accountNumber, authenticationMode, email, firstName, + lastName, mobileNumber, password, username) } else { Toaster.show(root, getString(R.string.no_internet_connection)) } diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt index 71cc01a28..9dd0c042d 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt @@ -1,6 +1,6 @@ package org.mifos.mobile.viewModels -import android.util.Patterns +import androidx.core.util.PatternsCompat import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -9,16 +9,13 @@ import io.reactivex.disposables.CompositeDisposable import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody -import org.mifos.mobile.RegistrationRepository -import org.mifos.mobile.api.DataManager -import org.mifos.mobile.models.register.RegisterPayload +import org.mifos.mobile.repositories.UserAuthRepositoryImp import org.mifos.mobile.utils.RegistrationUiState import javax.inject.Inject -class RegistrationViewModel @Inject constructor(var dataManager : DataManager?) : ViewModel() { +class RegistrationViewModel @Inject constructor(private var userAuthRepositoryImp: UserAuthRepositoryImp?) : ViewModel() { private val compositeDisposables: CompositeDisposable = CompositeDisposable() - private val registrationRepository = RegistrationRepository(dataManager) private val _registrationUiState = MutableLiveData() val registrationUiState : LiveData get() = _registrationUiState @@ -39,26 +36,15 @@ class RegistrationViewModel @Inject constructor(var dataManager : DataManager?) } fun isEmailInvalid(emailText : String) : Boolean { - return !Patterns.EMAIL_ADDRESS.matcher(emailText.trim()).matches() + return !PatternsCompat.EMAIL_ADDRESS.matcher(emailText.trim()).matches() } - fun createRegisterPayload( - accountNumber: String, - authenticationMode: String, - email: String, - firstName: String, - lastName: String, - mobileNumber: String, - password: String, - username: String - ) : RegisterPayload { - return registrationRepository.createRegisterPayload(accountNumber, authenticationMode, email, firstName, - lastName, mobileNumber, password, username) - } - - fun registerUser(registerPayload: RegisterPayload?) { + fun registerUser(accountNumber: String, authenticationMode: String, email: String, + firstName: String, lastName: String, mobileNumber: String, password: String, + username: String) { _registrationUiState.value = RegistrationUiState.Loading - registrationRepository.registerUser(registerPayload) + userAuthRepositoryImp?.registerUser(accountNumber, authenticationMode, email, firstName, + lastName, mobileNumber, password, username) ?.observeOn(AndroidSchedulers.mainThread()) ?.subscribeOn(Schedulers.io()) ?.subscribeWith(object : DisposableObserver() { diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt index dd0d3089b..b01902d1b 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt @@ -2,17 +2,17 @@ package org.mifos.mobile.viewModels import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import org.mifos.mobile.api.DataManager +import org.mifos.mobile.repositories.UserAuthRepositoryImp import org.mifos.mobile.injection.PerActivity import javax.inject.Inject @PerActivity -class RegistrationViewModelFactory @Inject constructor(private val dataManager: DataManager?) : +class RegistrationViewModelFactory @Inject constructor(private val userAuthRepositoryImp: UserAuthRepositoryImp?) : ViewModelProvider.Factory { override fun create(modelClass: Class): T { if(modelClass.isAssignableFrom(RegistrationViewModel::class.java)) { - return RegistrationViewModel(dataManager) as T + return RegistrationViewModel(userAuthRepositoryImp) as T } throw IllegalArgumentException("Unknown ViewModel class: " + modelClass.name) } diff --git a/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt b/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt new file mode 100644 index 000000000..93c7ce0fd --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt @@ -0,0 +1,80 @@ +package org.mifos.mobile.repositories + +import io.reactivex.Observable +import okhttp3.ResponseBody +import org.junit.After +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.register.RegisterPayload +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner + +@RunWith(MockitoJUnitRunner::class) +class UserAuthRepositoryImpTest { + + @Mock + lateinit var dataManager : DataManager + + private lateinit var userAuthRepositoryImp: UserAuthRepositoryImp + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + userAuthRepositoryImp = UserAuthRepositoryImp(dataManager) + } + + @Test + fun testRegisterUser_SuccessResponseReceivedFromDataManager_ReturnSuccessfulRegistration() { + val successResponse : Observable = Observable.just(Mockito.mock(ResponseBody::class.java)) + val registerPayload = RegisterPayload().apply { + this.accountNumber = "accountNumber" + this.authenticationMode = "authenticationMode" + this.email = "email" + this.firstName = "firstName" + this.lastName = "lastName" + this.mobileNumber = "mobileNumber" + this.password = "password" + this.username = "username" + } + + Mockito.`when`(dataManager.registerUser(registerPayload)) + .thenReturn(successResponse) + + val result = userAuthRepositoryImp.registerUser(registerPayload.accountNumber, + registerPayload.authenticationMode, registerPayload.email, registerPayload.firstName, + registerPayload.lastName, registerPayload.mobileNumber, registerPayload.password, registerPayload.username) + + Mockito.verify(dataManager).registerUser(registerPayload) + Assert.assertEquals(result, successResponse) + } + + @Test + fun testRegisterUser_ErrorResponseReceivedFromDataManager_ReturnsUnsuccessfulRegistration() { + val error : Observable = Observable.error(Throwable("Registration Failed")) + val registerPayload = RegisterPayload().apply { + this.accountNumber = "accountNumber" + this.authenticationMode = "authenticationMode" + this.email = "email" + this.firstName = "firstName" + this.lastName = "lastName" + this.mobileNumber = "mobileNumber" + this.password = "password" + this.username = "username" + } + + Mockito.`when`(dataManager.registerUser(registerPayload)) + .thenReturn(error) + + val result = userAuthRepositoryImp.registerUser(registerPayload.accountNumber, + registerPayload.authenticationMode, registerPayload.email, registerPayload.firstName, + registerPayload.lastName, registerPayload.mobileNumber, registerPayload.password, registerPayload.username) + + Mockito.verify(dataManager).registerUser(registerPayload) + Assert.assertEquals(result, error) + } +} \ No newline at end of file diff --git a/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt new file mode 100644 index 000000000..aa7567275 --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt @@ -0,0 +1,148 @@ +package org.mifos.mobile.viewModels + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import androidx.lifecycle.Observer +import io.reactivex.Observable +import okhttp3.ResponseBody +import org.junit.After +import org.junit.Assert +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mifos.mobile.repositories.UserAuthRepositoryImp +import org.mifos.mobile.util.RxSchedulersOverrideRule +import org.mifos.mobile.utils.RegistrationUiState +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner +import java.lang.RuntimeException + +@RunWith(MockitoJUnitRunner::class) +class RegistrationViewModelTest { + + @JvmField + @Rule + val mOverrideSchedulersRule = RxSchedulersOverrideRule() + + @get:Rule + val rule = InstantTaskExecutorRule() + + @Mock + lateinit var userAuthRepositoryImp : UserAuthRepositoryImp + + @Mock + lateinit var registrationUiStateObserver: Observer + + private lateinit var registrationViewModel: RegistrationViewModel + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + registrationViewModel = RegistrationViewModel(userAuthRepositoryImp) + registrationViewModel.registrationUiState.observeForever(registrationUiStateObserver) + } + + @Test + fun testIsInputFieldBlank_WithNonEmptyStringInput_ReturnsFalse() { + val result = registrationViewModel.isInputFieldBlank("nonEmptyTestString") + Assert.assertFalse(result) + } + + @Test + fun testIsInputFieldBlank_WithEmptyStringInput_ReturnsTrue() { + val result = registrationViewModel.isInputFieldBlank("") + Assert.assertTrue(result) + } + + @Test + fun testIsInputLengthInadequate_WithAdequateLengthInput_ReturnsFalse() { + val result = registrationViewModel.isInputLengthInadequate("Password123") + Assert.assertFalse(result) + } + + @Test + fun testIsInputLengthInadequate_WithInadequateLengthInput_ReturnsTrue() { + val result = registrationViewModel.isInputLengthInadequate("") + Assert.assertTrue(result) + } + + @Test + fun testInputHasSpaces_WithSpacesInput_ReturnsTrue() { + val result = registrationViewModel.inputHasSpaces("test string") + Assert.assertTrue(result) + } + + @Test + fun testInputHasSpaces_WithNoSpacesInput_ReturnsFalse() { + val result = registrationViewModel.inputHasSpaces("testString") + Assert.assertFalse(result) + } + + @Test + fun testHasLeadingTrailingSpaces_WithLeadingTrailingSpacesInput_ReturnsTrue() { + val result = registrationViewModel.hasLeadingTrailingSpaces(" Hello World ") + Assert.assertTrue(result) + } + + @Test + fun testHasLeadingTrailingSpaces_WithoutLeadingTrailingSpacesInput_ReturnsFalse() { + val result = registrationViewModel.hasLeadingTrailingSpaces("Hello World") + Assert.assertFalse(result) + } + + @Test + fun testIsEmailInvalid_WithValidEmailInput_ReturnsFalse() { + val result = registrationViewModel.isEmailInvalid("test@example.com") + Assert.assertFalse(result) + } + + @Test + fun testIsEmailInvalid_WithInvalidEmailInput_ReturnsTrue() { + val result = registrationViewModel.isEmailInvalid("testExample.com") + Assert.assertTrue(result) + } + + + @Test + fun testRegisterUser_SuccessfulRegistrationReceivedFromRepository_ReturnsRegistrationSuccessful() { + val responseBody = Mockito.mock(ResponseBody::class.java) + Mockito.`when`( + userAuthRepositoryImp.registerUser(Mockito.anyString(), Mockito.anyString(), + Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), + Mockito.anyString(), Mockito.anyString(),) + ).thenReturn(Observable.just(responseBody)) + + registrationViewModel.registerUser("accountNumber", "authMode", + "email", "firstName", "lastName", "mobileNumber", "password" + , "userName") + + Mockito.verify(registrationUiStateObserver).onChanged(RegistrationUiState.Loading) + Mockito.verify(registrationUiStateObserver).onChanged(RegistrationUiState.RegistrationSuccessful) + Mockito.verifyNoMoreInteractions(registrationUiStateObserver) + } + + @Test + fun testRegisterUser_UnsuccessfulRegistrationReceivedFromRepository_ReturnsRegistrationUnsuccessful() { + val error = RuntimeException("Registration Failed") + Mockito.`when`( + userAuthRepositoryImp.registerUser( + Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), + Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()) + ).thenReturn(Observable.error(error)) + + registrationViewModel.registerUser("accountNumber", + "authMode", "email", "firstName", "lastName", + "mobileNumber", "password", "username") + + Mockito.verify(registrationUiStateObserver).onChanged(RegistrationUiState.Loading) + Mockito.verify(registrationUiStateObserver).onChanged(RegistrationUiState.ErrorOnRegistration(error)) + Mockito.verifyNoMoreInteractions(registrationUiStateObserver) + } + + @After + fun tearDown() { + registrationViewModel.registrationUiState.removeObserver(registrationUiStateObserver) + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 942acd60c..072c46a69 100644 --- a/build.gradle +++ b/build.gradle @@ -68,7 +68,7 @@ ext { kotlinVersion = '1.6.10' tableViewVersion = '0.8.9.4' biometric = '1.1.0' - + archCoreVersion = '2.2.0' jUnitVersion = '4.13.2' mockitoVersion = '5.3.1' runnerVersion = '1.6.0-alpha02' From 0a889137e9e72ea41d5357b8430d5ee22496b315 Mon Sep 17 00:00:00 2001 From: Pratyush Singh Date: Sun, 2 Jul 2023 01:20:16 +0530 Subject: [PATCH 09/35] feat: data displayed in the home fragment --- .../org/mifos/mobile/MifosSelfServiceApp.kt | 2 -- .../mobile/api/local/PreferencesHelper.kt | 2 +- .../mifos/mobile/injection/ActivityContext.kt | 6 ++-- .../mobile/injection/ApplicationContext.kt | 6 ++-- .../injection/component/ActivityComponent.kt | 8 +++--- .../component/ApplicationComponent.kt | 22 +++++++++------ .../mobile/injection/module/ActivityModule.kt | 22 ++++++++------- .../injection/module/ApplicationModule.kt | 28 ++++++++++++------- .../presenters/AccountOverviewPresenter.kt | 2 +- .../mobile/presenters/AccountsPresenter.kt | 2 +- .../presenters/AddGuarantorPresenter.kt | 4 ++- .../BeneficiaryApplicationPresenter.kt | 2 +- .../presenters/BeneficiaryDetailPresenter.kt | 2 +- .../presenters/BeneficiaryListPresenter.kt | 2 +- .../presenters/ClientChargePresenter.kt | 4 ++- .../presenters/GuarantorDetailPresenter.kt | 2 +- .../presenters/GuarantorListPresenter.kt | 2 +- .../mifos/mobile/presenters/HelpPresenter.kt | 2 +- .../mobile/presenters/HomeOldPresenter.kt | 4 ++- .../mifos/mobile/presenters/HomePresenter.kt | 2 +- .../LoanAccountWithdrawPresenter.kt | 2 +- .../presenters/LoanAccountsDetailPresenter.kt | 2 +- .../LoanAccountsTransactionPresenter.kt | 2 +- .../presenters/LoanApplicationPresenter.kt | 2 +- .../LoanRepaymentSchedulePresenter.kt | 2 +- .../mifos/mobile/presenters/LoginPresenter.kt | 2 +- .../presenters/NotificationPresenter.kt | 7 +++-- .../presenters/QrCodeImportPresenter.kt | 2 +- .../presenters/RecentTransactionsPresenter.kt | 2 +- .../presenters/RegistrationPresenter.kt | 2 +- .../RegistrationVerificationPresenter.kt | 2 +- .../SavingAccountsDetailPresenter.kt | 2 +- .../SavingAccountsTransactionPresenter.kt | 2 +- .../SavingsAccountApplicationPresenter.kt | 2 +- .../SavingsAccountWithdrawPresenter.kt | 2 +- .../SavingsMakeTransferPresenter.kt | 2 +- .../presenters/ThirdPartyTransferPresenter.kt | 2 +- .../presenters/TransferProcessPresenter.kt | 2 +- .../presenters/UpdatePasswordPresenter.kt | 2 +- .../mobile/presenters/UserDetailsPresenter.kt | 2 +- .../mobile/ui/activities/HomeActivity.kt | 2 ++ .../mobile/ui/activities/LoginActivity.kt | 2 ++ .../mobile/ui/activities/base/BaseActivity.kt | 27 +++++++++--------- .../mifos/mobile/ui/adapters/FAQAdapter.kt | 4 ++- .../mobile/ui/adapters/NotificationAdapter.kt | 4 ++- .../adapters/RecentTransactionListAdapter.kt | 4 ++- .../mobile/ui/fragments/HomeOldFragment.kt | 2 ++ .../ReviewLoanApplicationFragment.kt | 2 +- .../ui/widgets/ChargeWidgetDataProvider.kt | 2 +- 49 files changed, 126 insertions(+), 94 deletions(-) diff --git a/app/src/main/java/org/mifos/mobile/MifosSelfServiceApp.kt b/app/src/main/java/org/mifos/mobile/MifosSelfServiceApp.kt index 326d7528e..a64f9ab20 100644 --- a/app/src/main/java/org/mifos/mobile/MifosSelfServiceApp.kt +++ b/app/src/main/java/org/mifos/mobile/MifosSelfServiceApp.kt @@ -12,8 +12,6 @@ import dagger.hilt.android.EntryPointAccessors import dagger.hilt.android.HiltAndroidApp import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.injection.component.ApplicationComponent -import org.mifos.mobile.injection.component.DaggerApplicationComponent -import org.mifos.mobile.injection.module.ApplicationModule import org.mifos.mobile.ui.fragments.applySavedTheme import org.mifos.mobile.utils.LanguageHelper.onAttach import java.util.Locale diff --git a/app/src/main/java/org/mifos/mobile/api/local/PreferencesHelper.kt b/app/src/main/java/org/mifos/mobile/api/local/PreferencesHelper.kt index 6bcc8d43d..5d383afcb 100644 --- a/app/src/main/java/org/mifos/mobile/api/local/PreferencesHelper.kt +++ b/app/src/main/java/org/mifos/mobile/api/local/PreferencesHelper.kt @@ -4,9 +4,9 @@ import android.content.Context import android.content.SharedPreferences import android.preference.PreferenceManager import android.text.TextUtils +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.api.BaseURL import org.mifos.mobile.api.SelfServiceInterceptor -import org.mifos.mobile.injection.ApplicationContext import org.mifos.mobile.ui.fragments.AppTheme import javax.inject.Inject import javax.inject.Singleton diff --git a/app/src/main/java/org/mifos/mobile/injection/ActivityContext.kt b/app/src/main/java/org/mifos/mobile/injection/ActivityContext.kt index d03aab08a..668cbd74e 100644 --- a/app/src/main/java/org/mifos/mobile/injection/ActivityContext.kt +++ b/app/src/main/java/org/mifos/mobile/injection/ActivityContext.kt @@ -6,6 +6,6 @@ import javax.inject.Qualifier * @author ishan * @since 08/07/16 */ -@Qualifier -@Retention(AnnotationRetention.RUNTIME) -annotation class ActivityContext +//@Qualifier +//@Retention(AnnotationRetention.RUNTIME) +//annotation class ActivityContext diff --git a/app/src/main/java/org/mifos/mobile/injection/ApplicationContext.kt b/app/src/main/java/org/mifos/mobile/injection/ApplicationContext.kt index 79248bd6d..f835ce7dc 100644 --- a/app/src/main/java/org/mifos/mobile/injection/ApplicationContext.kt +++ b/app/src/main/java/org/mifos/mobile/injection/ApplicationContext.kt @@ -6,6 +6,6 @@ import javax.inject.Qualifier * @author ishan * @since 08/07/16 */ -@Qualifier -@Retention(AnnotationRetention.RUNTIME) -annotation class ApplicationContext +//@Qualifier +//@Retention(AnnotationRetention.RUNTIME) +//annotation class ApplicationContext diff --git a/app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt b/app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt index e2053fe2f..c4401ca8f 100644 --- a/app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt +++ b/app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt @@ -51,10 +51,10 @@ import org.mifos.mobile.ui.fragments.UserProfileFragment * @author ishan * @since 08/07/16 */ -@PerActivity -@InstallIn(SingletonComponent::class) -@EntryPoint -@Component(dependencies = [ApplicationComponent::class], modules = [ActivityModule::class]) +//@PerActivity +//@InstallIn(SingletonComponent::class) +//@EntryPoint +//@Component(dependencies = [ApplicationComponent::class], modules = [ActivityModule::class]) interface ActivityComponent { fun inject(loginActivity: LoginActivity?) fun inject(homeActivity: HomeActivity?) diff --git a/app/src/main/java/org/mifos/mobile/injection/component/ApplicationComponent.kt b/app/src/main/java/org/mifos/mobile/injection/component/ApplicationComponent.kt index b6982275c..19788b9ae 100644 --- a/app/src/main/java/org/mifos/mobile/injection/component/ApplicationComponent.kt +++ b/app/src/main/java/org/mifos/mobile/injection/component/ApplicationComponent.kt @@ -3,11 +3,14 @@ package org.mifos.mobile.injection.component import android.app.Application import android.content.Context import dagger.Component +import dagger.hilt.EntryPoint +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent import org.mifos.mobile.api.BaseApiManager import org.mifos.mobile.api.DataManager import org.mifos.mobile.api.local.DatabaseHelper import org.mifos.mobile.api.local.PreferencesHelper -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.injection.module.ApplicationModule import javax.inject.Singleton @@ -16,13 +19,14 @@ import javax.inject.Singleton * @since 08/07/16 */ @Singleton -@Component(modules = [ApplicationModule::class]) +@InstallIn(SingletonComponent::class) +@EntryPoint interface ApplicationComponent { - @ApplicationContext - fun context(): Context? - fun application(): Application? - fun dataManager(): DataManager? - fun prefManager(): PreferencesHelper? - fun baseApiManager(): BaseApiManager? - fun databaseHelper(): DatabaseHelper? +// @ApplicationContext +// fun context(): Context? +// fun application(): Application? +// fun dataManager(): DataManager? +// fun prefManager(): PreferencesHelper? +// fun baseApiManager(): BaseApiManager? +// fun databaseHelper(): DatabaseHelper? } diff --git a/app/src/main/java/org/mifos/mobile/injection/module/ActivityModule.kt b/app/src/main/java/org/mifos/mobile/injection/module/ActivityModule.kt index 6ae26e1fb..f08b838bc 100644 --- a/app/src/main/java/org/mifos/mobile/injection/module/ActivityModule.kt +++ b/app/src/main/java/org/mifos/mobile/injection/module/ActivityModule.kt @@ -6,7 +6,9 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import org.mifos.mobile.injection.ActivityContext +import dagger.hilt.android.qualifiers.ActivityContext + + /** * @author ishan @@ -15,14 +17,14 @@ import org.mifos.mobile.injection.ActivityContext @Module @InstallIn(SingletonComponent::class) class ActivityModule(private val activity: Activity? = null) { - @Provides - fun providesActivity(): Activity { - return activity!! - } +// @Provides +// fun providesActivity(): Activity { +// return activity!! +// } - @Provides - @ActivityContext - fun providesContext(): Context { - return activity!! - } +// @Provides +// @ActivityContext +// fun providesContext(): Context { +// return activity!! +// } } diff --git a/app/src/main/java/org/mifos/mobile/injection/module/ApplicationModule.kt b/app/src/main/java/org/mifos/mobile/injection/module/ApplicationModule.kt index 96042c3c8..07ceea2cf 100644 --- a/app/src/main/java/org/mifos/mobile/injection/module/ApplicationModule.kt +++ b/app/src/main/java/org/mifos/mobile/injection/module/ApplicationModule.kt @@ -5,10 +5,12 @@ import android.content.Context import dagger.Module import dagger.Provides import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent import org.mifos.mobile.api.BaseApiManager +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.api.local.DatabaseHelper import org.mifos.mobile.api.local.PreferencesHelper -import org.mifos.mobile.injection.ApplicationContext import javax.inject.Singleton /** @@ -18,16 +20,16 @@ import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) class ApplicationModule(private val application: Application? = null) { - @Provides - fun provideApplication(): Application { - return application!! - } +// @Provides +// fun provideApplication(): Application { +// return application!! +// } - @Provides - @ApplicationContext - fun provideContext(): Context { - return application!! - } +// @Provides +// @ApplicationContext +// fun provideContext(): Context { +// return application!! +// } @Provides @Singleton @@ -40,4 +42,10 @@ class ApplicationModule(private val application: Application? = null) { fun provideBaseApiManager(preferencesHelper: PreferencesHelper?): BaseApiManager { return BaseApiManager(preferencesHelper!!) } + + @Provides + @Singleton + fun providesDataManager(preferencesHelper: PreferencesHelper?, baseApiManager: BaseApiManager?, databaseHelper: DatabaseHelper): DataManager { + return DataManager(preferencesHelper!!, baseApiManager!!, databaseHelper!!) + } } diff --git a/app/src/main/java/org/mifos/mobile/presenters/AccountOverviewPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/AccountOverviewPresenter.kt index 8a98dde09..642c33068 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/AccountOverviewPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/AccountOverviewPresenter.kt @@ -7,7 +7,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.accounts.loan.LoanAccount import org.mifos.mobile.models.accounts.savings.SavingAccount import org.mifos.mobile.models.client.ClientAccounts diff --git a/app/src/main/java/org/mifos/mobile/presenters/AccountsPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/AccountsPresenter.kt index 84c559c55..e625d7ae9 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/AccountsPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/AccountsPresenter.kt @@ -9,7 +9,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.CheckboxStatus import org.mifos.mobile.models.accounts.loan.LoanAccount import org.mifos.mobile.models.accounts.savings.SavingAccount diff --git a/app/src/main/java/org/mifos/mobile/presenters/AddGuarantorPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/AddGuarantorPresenter.kt index 0ca554a72..27b4d6689 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/AddGuarantorPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/AddGuarantorPresenter.kt @@ -8,7 +8,9 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ActivityContext +import dagger.hilt.android.qualifiers.ActivityContext + + import org.mifos.mobile.models.guarantor.GuarantorApplicationPayload import org.mifos.mobile.models.guarantor.GuarantorTemplatePayload import org.mifos.mobile.presenters.base.BasePresenter diff --git a/app/src/main/java/org/mifos/mobile/presenters/BeneficiaryApplicationPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/BeneficiaryApplicationPresenter.kt index af026c36c..b87bd3694 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/BeneficiaryApplicationPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/BeneficiaryApplicationPresenter.kt @@ -9,7 +9,7 @@ import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.beneficiary.BeneficiaryPayload import org.mifos.mobile.models.beneficiary.BeneficiaryUpdatePayload import org.mifos.mobile.models.templates.beneficiary.BeneficiaryTemplate diff --git a/app/src/main/java/org/mifos/mobile/presenters/BeneficiaryDetailPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/BeneficiaryDetailPresenter.kt index fcd1f3237..bfd1e9545 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/BeneficiaryDetailPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/BeneficiaryDetailPresenter.kt @@ -8,7 +8,7 @@ import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.BeneficiaryDetailView import javax.inject.Inject diff --git a/app/src/main/java/org/mifos/mobile/presenters/BeneficiaryListPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/BeneficiaryListPresenter.kt index e68135957..c84a8771e 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/BeneficiaryListPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/BeneficiaryListPresenter.kt @@ -7,7 +7,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.beneficiary.Beneficiary import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.BeneficiariesView diff --git a/app/src/main/java/org/mifos/mobile/presenters/ClientChargePresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/ClientChargePresenter.kt index 7583f30be..f265c424a 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/ClientChargePresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/ClientChargePresenter.kt @@ -7,7 +7,9 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ActivityContext +import dagger.hilt.android.qualifiers.ActivityContext + + import org.mifos.mobile.models.Charge import org.mifos.mobile.models.Page import org.mifos.mobile.presenters.base.BasePresenter diff --git a/app/src/main/java/org/mifos/mobile/presenters/GuarantorDetailPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/GuarantorDetailPresenter.kt index c32389e6d..127cab091 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/GuarantorDetailPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/GuarantorDetailPresenter.kt @@ -8,7 +8,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.GuarantorDetailView import java.io.IOException diff --git a/app/src/main/java/org/mifos/mobile/presenters/GuarantorListPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/GuarantorListPresenter.kt index fd0c8f305..eabf305c8 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/GuarantorListPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/GuarantorListPresenter.kt @@ -6,7 +6,7 @@ import io.reactivex.disposables.CompositeDisposable import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.guarantor.GuarantorPayload import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.GuarantorListView diff --git a/app/src/main/java/org/mifos/mobile/presenters/HelpPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/HelpPresenter.kt index 862899aff..2276b253d 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/HelpPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/HelpPresenter.kt @@ -2,7 +2,7 @@ package org.mifos.mobile.presenters import android.content.Context import org.mifos.mobile.R -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.FAQ import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.HelpView diff --git a/app/src/main/java/org/mifos/mobile/presenters/HomeOldPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/HomeOldPresenter.kt index a68b56635..4d1af7355 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/HomeOldPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/HomeOldPresenter.kt @@ -4,6 +4,9 @@ import android.content.Context import android.graphics.Bitmap import android.util.Base64 import android.util.Log +import dagger.hilt.android.AndroidEntryPoint +import dagger.hilt.android.qualifiers.ActivityContext +import dagger.hilt.android.qualifiers.ApplicationContext import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.observers.DisposableObserver @@ -12,7 +15,6 @@ import okhttp3.ResponseBody import org.mifos.mobile.R import org.mifos.mobile.api.DataManager import org.mifos.mobile.api.local.PreferencesHelper -import org.mifos.mobile.injection.ActivityContext import org.mifos.mobile.models.accounts.loan.LoanAccount import org.mifos.mobile.models.accounts.savings.SavingAccount import org.mifos.mobile.models.client.Client diff --git a/app/src/main/java/org/mifos/mobile/presenters/HomePresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/HomePresenter.kt index e5b40d709..1e9425f40 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/HomePresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/HomePresenter.kt @@ -12,7 +12,7 @@ import okhttp3.ResponseBody import org.mifos.mobile.R import org.mifos.mobile.api.DataManager import org.mifos.mobile.api.local.PreferencesHelper -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.client.Client import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.HomeView diff --git a/app/src/main/java/org/mifos/mobile/presenters/LoanAccountWithdrawPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/LoanAccountWithdrawPresenter.kt index 8b71ea4ad..47684caca 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/LoanAccountWithdrawPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/LoanAccountWithdrawPresenter.kt @@ -8,7 +8,7 @@ import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.accounts.loan.LoanWithdraw import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.LoanAccountWithdrawView diff --git a/app/src/main/java/org/mifos/mobile/presenters/LoanAccountsDetailPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/LoanAccountsDetailPresenter.kt index e0716f4d0..d1908111a 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/LoanAccountsDetailPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/LoanAccountsDetailPresenter.kt @@ -7,7 +7,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.accounts.loan.LoanWithAssociations import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.LoanAccountsDetailView diff --git a/app/src/main/java/org/mifos/mobile/presenters/LoanAccountsTransactionPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/LoanAccountsTransactionPresenter.kt index f2fa0f163..489b3ba52 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/LoanAccountsTransactionPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/LoanAccountsTransactionPresenter.kt @@ -7,7 +7,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.accounts.loan.LoanWithAssociations import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.LoanAccountsTransactionView diff --git a/app/src/main/java/org/mifos/mobile/presenters/LoanApplicationPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/LoanApplicationPresenter.kt index 48aba11bd..0c2baf4c1 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/LoanApplicationPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/LoanApplicationPresenter.kt @@ -7,7 +7,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.templates.loans.LoanTemplate import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.enums.LoanState diff --git a/app/src/main/java/org/mifos/mobile/presenters/LoanRepaymentSchedulePresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/LoanRepaymentSchedulePresenter.kt index 84c7693db..8f33c4fe9 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/LoanRepaymentSchedulePresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/LoanRepaymentSchedulePresenter.kt @@ -7,7 +7,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.accounts.loan.LoanWithAssociations import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.LoanRepaymentScheduleMvpView diff --git a/app/src/main/java/org/mifos/mobile/presenters/LoginPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/LoginPresenter.kt index 2fc997225..eddd5f085 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/LoginPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/LoginPresenter.kt @@ -10,7 +10,7 @@ import org.mifos.mobile.R import org.mifos.mobile.api.BaseApiManager import org.mifos.mobile.api.DataManager import org.mifos.mobile.api.local.PreferencesHelper -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.Page import org.mifos.mobile.models.User import org.mifos.mobile.models.client.Client diff --git a/app/src/main/java/org/mifos/mobile/presenters/NotificationPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/NotificationPresenter.kt index 361dc62ca..b59e8c33e 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/NotificationPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/NotificationPresenter.kt @@ -1,13 +1,16 @@ package org.mifos.mobile.presenters import android.content.Context +import dagger.hilt.android.qualifiers.ApplicationContext import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ActivityContext +import dagger.hilt.android.qualifiers.ActivityContext + + import org.mifos.mobile.models.notification.MifosNotification import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.NotificationView @@ -18,7 +21,7 @@ import javax.inject.Inject */ class NotificationPresenter @Inject constructor( private val manager: DataManager?, - @ActivityContext context: Context?, + @ApplicationContext context: Context?, ) : BasePresenter(context) { diff --git a/app/src/main/java/org/mifos/mobile/presenters/QrCodeImportPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/QrCodeImportPresenter.kt index 733452867..840a9e58a 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/QrCodeImportPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/QrCodeImportPresenter.kt @@ -16,7 +16,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.schedulers.Schedulers import org.mifos.mobile.R -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.QrCodeImportView import java.util.EnumMap diff --git a/app/src/main/java/org/mifos/mobile/presenters/RecentTransactionsPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/RecentTransactionsPresenter.kt index 7e1be07d5..f4b8d86d6 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/RecentTransactionsPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/RecentTransactionsPresenter.kt @@ -7,7 +7,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.Page import org.mifos.mobile.models.Transaction import org.mifos.mobile.presenters.base.BasePresenter diff --git a/app/src/main/java/org/mifos/mobile/presenters/RegistrationPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/RegistrationPresenter.kt index 3f56ba955..b383c9340 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/RegistrationPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/RegistrationPresenter.kt @@ -7,7 +7,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.register.RegisterPayload import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.RegistrationView diff --git a/app/src/main/java/org/mifos/mobile/presenters/RegistrationVerificationPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/RegistrationVerificationPresenter.kt index 0f461a199..c07e3f2f9 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/RegistrationVerificationPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/RegistrationVerificationPresenter.kt @@ -7,7 +7,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.register.UserVerify import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.RegistrationVerificationView diff --git a/app/src/main/java/org/mifos/mobile/presenters/SavingAccountsDetailPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/SavingAccountsDetailPresenter.kt index 7b32314a2..057db9086 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/SavingAccountsDetailPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/SavingAccountsDetailPresenter.kt @@ -7,7 +7,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.accounts.savings.SavingsWithAssociations import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.SavingAccountsDetailView diff --git a/app/src/main/java/org/mifos/mobile/presenters/SavingAccountsTransactionPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/SavingAccountsTransactionPresenter.kt index ef5d4b9ad..b74f6b4fe 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/SavingAccountsTransactionPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/SavingAccountsTransactionPresenter.kt @@ -9,7 +9,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.CheckboxStatus import org.mifos.mobile.models.accounts.savings.SavingsWithAssociations import org.mifos.mobile.models.accounts.savings.Transactions diff --git a/app/src/main/java/org/mifos/mobile/presenters/SavingsAccountApplicationPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/SavingsAccountApplicationPresenter.kt index 94bc32997..9ab616b3e 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/SavingsAccountApplicationPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/SavingsAccountApplicationPresenter.kt @@ -7,7 +7,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.accounts.savings.SavingsAccountApplicationPayload import org.mifos.mobile.models.accounts.savings.SavingsAccountUpdatePayload import org.mifos.mobile.models.templates.savings.SavingsAccountTemplate diff --git a/app/src/main/java/org/mifos/mobile/presenters/SavingsAccountWithdrawPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/SavingsAccountWithdrawPresenter.kt index 286019e4f..b6e3c2284 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/SavingsAccountWithdrawPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/SavingsAccountWithdrawPresenter.kt @@ -7,7 +7,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.accounts.savings.SavingsAccountWithdrawPayload import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.SavingsAccountWithdrawView diff --git a/app/src/main/java/org/mifos/mobile/presenters/SavingsMakeTransferPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/SavingsMakeTransferPresenter.kt index 44ce9581c..b1bc608cf 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/SavingsMakeTransferPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/SavingsMakeTransferPresenter.kt @@ -8,7 +8,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.payload.AccountDetail import org.mifos.mobile.models.templates.account.AccountOption import org.mifos.mobile.models.templates.account.AccountOptionsTemplate diff --git a/app/src/main/java/org/mifos/mobile/presenters/ThirdPartyTransferPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/ThirdPartyTransferPresenter.kt index 456bb47f5..7d5505dfc 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/ThirdPartyTransferPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/ThirdPartyTransferPresenter.kt @@ -9,7 +9,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.AccountOptionAndBeneficiary import org.mifos.mobile.models.beneficiary.Beneficiary import org.mifos.mobile.models.beneficiary.BeneficiaryDetail diff --git a/app/src/main/java/org/mifos/mobile/presenters/TransferProcessPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/TransferProcessPresenter.kt index 5afea342e..567a70f67 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/TransferProcessPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/TransferProcessPresenter.kt @@ -8,7 +8,7 @@ import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.mifos.mobile.R import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.payload.TransferPayload import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.TransferProcessView diff --git a/app/src/main/java/org/mifos/mobile/presenters/UpdatePasswordPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/UpdatePasswordPresenter.kt index 8181ec15b..4ed099e30 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/UpdatePasswordPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/UpdatePasswordPresenter.kt @@ -10,7 +10,7 @@ import okhttp3.ResponseBody import org.mifos.mobile.api.BaseApiManager.Companion.createService import org.mifos.mobile.api.DataManager import org.mifos.mobile.api.local.PreferencesHelper -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.UpdatePasswordPayload import org.mifos.mobile.presenters.base.BasePresenter import org.mifos.mobile.ui.views.UpdatePasswordView diff --git a/app/src/main/java/org/mifos/mobile/presenters/UserDetailsPresenter.kt b/app/src/main/java/org/mifos/mobile/presenters/UserDetailsPresenter.kt index fb90d13cc..ec530b608 100644 --- a/app/src/main/java/org/mifos/mobile/presenters/UserDetailsPresenter.kt +++ b/app/src/main/java/org/mifos/mobile/presenters/UserDetailsPresenter.kt @@ -12,7 +12,7 @@ import okhttp3.ResponseBody import org.mifos.mobile.R import org.mifos.mobile.api.DataManager import org.mifos.mobile.api.local.PreferencesHelper -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.client.Client import org.mifos.mobile.models.notification.NotificationRegisterPayload import org.mifos.mobile.models.notification.NotificationUserDetail diff --git a/app/src/main/java/org/mifos/mobile/ui/activities/HomeActivity.kt b/app/src/main/java/org/mifos/mobile/ui/activities/HomeActivity.kt index 299d9b09d..980fef106 100644 --- a/app/src/main/java/org/mifos/mobile/ui/activities/HomeActivity.kt +++ b/app/src/main/java/org/mifos/mobile/ui/activities/HomeActivity.kt @@ -22,6 +22,7 @@ import com.google.android.gms.common.GoogleApiAvailability import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.imageview.ShapeableImageView import com.google.android.material.navigation.NavigationView +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.databinding.ActivityHomeBinding @@ -51,6 +52,7 @@ import javax.inject.Inject * @author Vishwajeet * @since 14/07/2016 */ +@AndroidEntryPoint class HomeActivity : BaseActivity(), UserDetailsView, diff --git a/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt b/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt index f8c665369..064aeb5e4 100644 --- a/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt +++ b/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt @@ -6,6 +6,7 @@ import android.view.View import android.view.ViewGroup import android.widget.EditText import android.widget.Toast +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.ActivityLoginBinding import org.mifos.mobile.models.payload.LoginPayload @@ -21,6 +22,7 @@ import javax.inject.Inject * @author Vishwajeet * @since 05/06/16 */ +@AndroidEntryPoint class LoginActivity : BaseActivity(), LoginView { @JvmField diff --git a/app/src/main/java/org/mifos/mobile/ui/activities/base/BaseActivity.kt b/app/src/main/java/org/mifos/mobile/ui/activities/base/BaseActivity.kt index d736716a8..2aa40435f 100644 --- a/app/src/main/java/org/mifos/mobile/ui/activities/base/BaseActivity.kt +++ b/app/src/main/java/org/mifos/mobile/ui/activities/base/BaseActivity.kt @@ -13,11 +13,9 @@ import androidx.core.view.ViewCompat import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import com.mifos.mobile.passcode.BasePassCodeActivity -import org.mifos.mobile.MifosSelfServiceApp +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.injection.component.ActivityComponent -import org.mifos.mobile.injection.component.DaggerActivityComponent -import org.mifos.mobile.injection.module.ActivityModule import org.mifos.mobile.ui.activities.PassCodeActivity import org.mifos.mobile.ui.views.BaseActivityCallback import org.mifos.mobile.utils.LanguageHelper @@ -26,6 +24,7 @@ import org.mifos.mobile.utils.LanguageHelper * @author ishan * @since 08/07/16 */ +@AndroidEntryPoint @SuppressLint("Registered") open class BaseActivity : BasePassCodeActivity(), BaseActivityCallback { /** @@ -38,17 +37,17 @@ open class BaseActivity : BasePassCodeActivity(), BaseActivityCallback { * Used for dependency injection * @return [ActivityComponent] which is used for injection */ - var activityComponent: ActivityComponent? = null - get() { - if (field == null) { - field = DaggerActivityComponent.builder() - .activityModule(ActivityModule(this)) - .applicationComponent(MifosSelfServiceApp.get(this).component()) - .build() - } - return field - } - private set +// var activityComponent: ActivityComponent? = null +// get() { +// if (field == null) { +// field = DaggerActivityComponent.builder() +// .activityModule(ActivityModule(this)) +// .applicationComponent(MifosSelfServiceApp.get(this).component()) +// .build() +// } +// return field +// } +// private set private var progress: ProgressDialog? = null override fun setContentView(layoutResID: Int) { super.setContentView(layoutResID) diff --git a/app/src/main/java/org/mifos/mobile/ui/adapters/FAQAdapter.kt b/app/src/main/java/org/mifos/mobile/ui/adapters/FAQAdapter.kt index 6047fb849..29c916f77 100644 --- a/app/src/main/java/org/mifos/mobile/ui/adapters/FAQAdapter.kt +++ b/app/src/main/java/org/mifos/mobile/ui/adapters/FAQAdapter.kt @@ -8,7 +8,9 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import org.mifos.mobile.R import org.mifos.mobile.databinding.RowFaqBinding -import org.mifos.mobile.injection.ActivityContext +import dagger.hilt.android.qualifiers.ActivityContext + + import org.mifos.mobile.models.FAQ import org.mifos.mobile.utils.FaqDiffUtil import javax.inject.Inject diff --git a/app/src/main/java/org/mifos/mobile/ui/adapters/NotificationAdapter.kt b/app/src/main/java/org/mifos/mobile/ui/adapters/NotificationAdapter.kt index e7b77bbcf..21e3f39b7 100644 --- a/app/src/main/java/org/mifos/mobile/ui/adapters/NotificationAdapter.kt +++ b/app/src/main/java/org/mifos/mobile/ui/adapters/NotificationAdapter.kt @@ -6,9 +6,11 @@ import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView +import dagger.hilt.android.qualifiers.ActivityContext import org.mifos.mobile.R import org.mifos.mobile.databinding.RowNotificationBinding -import org.mifos.mobile.injection.ActivityContext + + import org.mifos.mobile.models.notification.MifosNotification import org.mifos.mobile.ui.getThemeAttributeColor import org.mifos.mobile.utils.DateHelper.getDateAndTimeAsStringFromLong diff --git a/app/src/main/java/org/mifos/mobile/ui/adapters/RecentTransactionListAdapter.kt b/app/src/main/java/org/mifos/mobile/ui/adapters/RecentTransactionListAdapter.kt index c8247c54e..79810406d 100644 --- a/app/src/main/java/org/mifos/mobile/ui/adapters/RecentTransactionListAdapter.kt +++ b/app/src/main/java/org/mifos/mobile/ui/adapters/RecentTransactionListAdapter.kt @@ -7,7 +7,9 @@ import androidx.recyclerview.widget.RecyclerView import org.mifos.mobile.MifosSelfServiceApp.Companion.context import org.mifos.mobile.R import org.mifos.mobile.databinding.RowRecentTransactionBinding -import org.mifos.mobile.injection.ActivityContext +import dagger.hilt.android.qualifiers.ActivityContext + + import org.mifos.mobile.models.Transaction import org.mifos.mobile.models.client.Type import org.mifos.mobile.utils.CurrencyUtil.formatCurrency diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt index 0914f2d2c..aabe77c70 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt @@ -20,6 +20,7 @@ import android.widget.TextView import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.databinding.FragmentHomeOldBinding @@ -45,6 +46,7 @@ import javax.inject.Inject /** * Created by michaelsosnick on 1/1/17. */ +@AndroidEntryPoint class HomeOldFragment : BaseFragment(), HomeOldView, OnRefreshListener { private var _binding: FragmentHomeOldBinding? = null private val binding get() = _binding!! diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt index 24d136a78..a8fb2e3a4 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt @@ -89,7 +89,7 @@ class ReviewLoanApplicationFragment : BaseFragment() { savedInstanceState: Bundle?, ): View { rootView = inflater.inflate(R.layout.fragment_review_loan_application, container, false) - (activity as BaseActivity).activityComponent?.inject(this) +// (activity as BaseActivity).activityComponent?.inject(this) viewModel = ViewModelProviders.of(this) .get(ReviewLoanApplicationViewModel::class.java) val loanState = arguments?.getSerializable(LOAN_STATE) as LoanState diff --git a/app/src/main/java/org/mifos/mobile/ui/widgets/ChargeWidgetDataProvider.kt b/app/src/main/java/org/mifos/mobile/ui/widgets/ChargeWidgetDataProvider.kt index f69a31600..c02184d77 100644 --- a/app/src/main/java/org/mifos/mobile/ui/widgets/ChargeWidgetDataProvider.kt +++ b/app/src/main/java/org/mifos/mobile/ui/widgets/ChargeWidgetDataProvider.kt @@ -9,7 +9,7 @@ import org.mifos.mobile.api.BaseApiManager import org.mifos.mobile.api.DataManager import org.mifos.mobile.api.local.DatabaseHelper import org.mifos.mobile.api.local.PreferencesHelper -import org.mifos.mobile.injection.ApplicationContext +import dagger.hilt.android.qualifiers.ApplicationContext import org.mifos.mobile.models.Charge import org.mifos.mobile.presenters.ClientChargePresenter import org.mifos.mobile.ui.views.ClientChargeView From 9f980b54d2fa4eff7134fb281ec7638396d54491 Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Sun, 2 Jul 2023 09:52:13 +0530 Subject: [PATCH 10/35] fix : testing with build fail, added two libs to test around build fail : 1. mockito-core 2. mockito-android --- app/build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 1f28ecb95..78d1e1c82 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -160,7 +160,8 @@ dependencies { // Unit tests dependencies testImplementation "junit:junit:$rootProject.jUnitVersion" testImplementation "org.mockito:mockito-core:$rootProject.mockitoVersion" - + implementation "org.mockito:mockito-core:$rootProject.mockitoVersion" + implementation "org.mockito:mockito-android:$rootProject.mockitoVersion" androidTestImplementation "junit:junit:$rootProject.jUnitVersion" androidTestImplementation "org.mockito:mockito-core:$rootProject.mockitoVersion" androidTestImplementation "org.mockito:mockito-android:$rootProject.mockitoVersion" From 7ccce6c212408551993e9ed5a3a7dcbd44cd8817 Mon Sep 17 00:00:00 2001 From: Pratyush Singh Date: Sun, 2 Jul 2023 11:16:14 +0530 Subject: [PATCH 11/35] feat: removed interfaces and annotations --- .../org/mifos/mobile/MifosSelfServiceApp.kt | 15 --- .../mifos/mobile/injection/ActivityContext.kt | 11 --- .../mobile/injection/ApplicationContext.kt | 11 --- .../injection/component/ActivityComponent.kt | 99 ------------------- .../component/ApplicationComponent.kt | 32 ------ .../injection/module/ApplicationModule.kt | 13 +-- .../mobile/ui/activities/base/BaseActivity.kt | 16 --- .../mobile/ui/fragments/AboutUsFragment.kt | 2 + .../ui/fragments/AccountOverviewFragment.kt | 2 + .../mobile/ui/fragments/AccountsFragment.kt | 2 + .../ui/fragments/AddGuarantorFragment.kt | 2 + .../BeneficiaryAddOptionsFragment.kt | 2 + .../BeneficiaryApplicationFragment.kt | 2 + .../ui/fragments/BeneficiaryDetailFragment.kt | 2 + .../ui/fragments/BeneficiaryListFragment.kt | 2 + .../ui/fragments/ClientAccountsFragment.kt | 5 +- .../ui/fragments/ClientChargeFragment.kt | 2 + .../ui/fragments/GuarantorDetailFragment.kt | 5 +- .../ui/fragments/GuarantorListFragment.kt | 2 + .../mifos/mobile/ui/fragments/HelpFragment.kt | 2 + .../fragments/LoanAccountSummaryFragment.kt | 2 + .../LoanAccountTransactionFragment.kt | 2 + .../fragments/LoanAccountWithdrawFragment.kt | 2 + .../fragments/LoanAccountsDetailFragment.kt | 2 + .../ui/fragments/LoanApplicationFragment.kt | 2 + .../LoanRepaymentScheduleFragment.kt | 2 + .../mobile/ui/fragments/LocationsFragment.kt | 2 + .../ui/fragments/NotificationFragment.kt | 2 + .../ui/fragments/QrCodeDisplayFragment.kt | 2 + .../ui/fragments/QrCodeImportFragment.kt | 2 + .../ui/fragments/QrCodeReaderFragment.kt | 2 + .../fragments/RecentTransactionsFragment.kt | 2 + .../ui/fragments/RegistrationFragment.kt | 2 + .../RegistrationVerificationFragment.kt | 2 + .../ReviewLoanApplicationFragment.kt | 2 + .../fragments/SavingAccountsDetailFragment.kt | 2 + .../SavingAccountsTransactionFragment.kt | 2 + .../SavingsAccountApplicationFragment.kt | 2 + .../SavingsAccountWithdrawFragment.kt | 2 + .../fragments/SavingsMakeTransferFragment.kt | 2 + .../mobile/ui/fragments/SettingsFragment.kt | 2 + .../fragments/ThirdPartyTransferFragment.kt | 2 + .../ui/fragments/TransferProcessFragment.kt | 2 + .../ui/fragments/UpdatePasswordFragment.kt | 5 +- .../ui/fragments/UserProfileFragment.kt | 2 + 45 files changed, 83 insertions(+), 199 deletions(-) delete mode 100644 app/src/main/java/org/mifos/mobile/injection/ActivityContext.kt delete mode 100644 app/src/main/java/org/mifos/mobile/injection/ApplicationContext.kt delete mode 100644 app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt delete mode 100644 app/src/main/java/org/mifos/mobile/injection/component/ApplicationComponent.kt diff --git a/app/src/main/java/org/mifos/mobile/MifosSelfServiceApp.kt b/app/src/main/java/org/mifos/mobile/MifosSelfServiceApp.kt index a64f9ab20..602999043 100644 --- a/app/src/main/java/org/mifos/mobile/MifosSelfServiceApp.kt +++ b/app/src/main/java/org/mifos/mobile/MifosSelfServiceApp.kt @@ -8,10 +8,8 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics import com.mifos.mobile.passcode.utils.ForegroundChecker import com.raizlabs.android.dbflow.config.FlowConfig import com.raizlabs.android.dbflow.config.FlowManager -import dagger.hilt.android.EntryPointAccessors import dagger.hilt.android.HiltAndroidApp import org.mifos.mobile.api.local.PreferencesHelper -import org.mifos.mobile.injection.component.ApplicationComponent import org.mifos.mobile.ui.fragments.applySavedTheme import org.mifos.mobile.utils.LanguageHelper.onAttach import java.util.Locale @@ -22,7 +20,6 @@ import java.util.Locale */ @HiltAndroidApp class MifosSelfServiceApp : MultiDexApplication() { - private var applicationComponent: ApplicationComponent? = null companion object { private var instance: MifosSelfServiceApp? = null @@ -51,16 +48,4 @@ class MifosSelfServiceApp : MultiDexApplication() { override fun attachBaseContext(base: Context) { super.attachBaseContext(onAttach(base, Locale.getDefault().language)) } - - fun component(): ApplicationComponent? { - if (applicationComponent == null) { - applicationComponent = EntryPointAccessors.fromApplication(this, ApplicationComponent::class.java) - } - return applicationComponent - } - - // Needed to replace the component with a test specific one - fun setComponent(applicationComponent: ApplicationComponent?) { - this.applicationComponent = applicationComponent - } } diff --git a/app/src/main/java/org/mifos/mobile/injection/ActivityContext.kt b/app/src/main/java/org/mifos/mobile/injection/ActivityContext.kt deleted file mode 100644 index 668cbd74e..000000000 --- a/app/src/main/java/org/mifos/mobile/injection/ActivityContext.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.mifos.mobile.injection - -import javax.inject.Qualifier - -/** - * @author ishan - * @since 08/07/16 - */ -//@Qualifier -//@Retention(AnnotationRetention.RUNTIME) -//annotation class ActivityContext diff --git a/app/src/main/java/org/mifos/mobile/injection/ApplicationContext.kt b/app/src/main/java/org/mifos/mobile/injection/ApplicationContext.kt deleted file mode 100644 index f835ce7dc..000000000 --- a/app/src/main/java/org/mifos/mobile/injection/ApplicationContext.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.mifos.mobile.injection - -import javax.inject.Qualifier - -/** - * @author ishan - * @since 08/07/16 - */ -//@Qualifier -//@Retention(AnnotationRetention.RUNTIME) -//annotation class ApplicationContext diff --git a/app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt b/app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt deleted file mode 100644 index c4401ca8f..000000000 --- a/app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt +++ /dev/null @@ -1,99 +0,0 @@ -package org.mifos.mobile.injection.component - -import dagger.Component -import dagger.hilt.EntryPoint -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import org.mifos.mobile.injection.PerActivity -import org.mifos.mobile.injection.module.ActivityModule -import org.mifos.mobile.ui.activities.HomeActivity -import org.mifos.mobile.ui.activities.LoginActivity -import org.mifos.mobile.ui.activities.PassCodeActivity -import org.mifos.mobile.ui.activities.SplashActivity -import org.mifos.mobile.ui.fragments.AccountOverviewFragment -import org.mifos.mobile.ui.fragments.AccountsFragment -import org.mifos.mobile.ui.fragments.AddGuarantorFragment -import org.mifos.mobile.ui.fragments.BeneficiaryAddOptionsFragment -import org.mifos.mobile.ui.fragments.BeneficiaryApplicationFragment -import org.mifos.mobile.ui.fragments.BeneficiaryDetailFragment -import org.mifos.mobile.ui.fragments.BeneficiaryListFragment -import org.mifos.mobile.ui.fragments.ClientAccountsFragment -import org.mifos.mobile.ui.fragments.ClientChargeFragment -import org.mifos.mobile.ui.fragments.GuarantorDetailFragment -import org.mifos.mobile.ui.fragments.GuarantorListFragment -import org.mifos.mobile.ui.fragments.HelpFragment -import org.mifos.mobile.ui.fragments.HomeFragment -import org.mifos.mobile.ui.fragments.HomeOldFragment -import org.mifos.mobile.ui.fragments.LoanAccountSummaryFragment -import org.mifos.mobile.ui.fragments.LoanAccountTransactionFragment -import org.mifos.mobile.ui.fragments.LoanAccountWithdrawFragment -import org.mifos.mobile.ui.fragments.LoanAccountsDetailFragment -import org.mifos.mobile.ui.fragments.LoanApplicationFragment -import org.mifos.mobile.ui.fragments.LoanRepaymentScheduleFragment -import org.mifos.mobile.ui.fragments.NotificationFragment -import org.mifos.mobile.ui.fragments.QrCodeImportFragment -import org.mifos.mobile.ui.fragments.QrCodeReaderFragment -import org.mifos.mobile.ui.fragments.RecentTransactionsFragment -import org.mifos.mobile.ui.fragments.RegistrationFragment -import org.mifos.mobile.ui.fragments.RegistrationVerificationFragment -import org.mifos.mobile.ui.fragments.ReviewLoanApplicationFragment -import org.mifos.mobile.ui.fragments.SavingAccountsDetailFragment -import org.mifos.mobile.ui.fragments.SavingAccountsTransactionFragment -import org.mifos.mobile.ui.fragments.SavingsAccountApplicationFragment -import org.mifos.mobile.ui.fragments.SavingsAccountWithdrawFragment -import org.mifos.mobile.ui.fragments.SavingsMakeTransferFragment -import org.mifos.mobile.ui.fragments.ThirdPartyTransferFragment -import org.mifos.mobile.ui.fragments.TransferProcessFragment -import org.mifos.mobile.ui.fragments.UpdatePasswordFragment -import org.mifos.mobile.ui.fragments.UserProfileFragment - -/** - * @author ishan - * @since 08/07/16 - */ -//@PerActivity -//@InstallIn(SingletonComponent::class) -//@EntryPoint -//@Component(dependencies = [ApplicationComponent::class], modules = [ActivityModule::class]) -interface ActivityComponent { - fun inject(loginActivity: LoginActivity?) - fun inject(homeActivity: HomeActivity?) - fun inject(passCodeActivity: PassCodeActivity?) - fun inject(homeFragment: HomeFragment?) - fun inject(clientAccountsFragment: ClientAccountsFragment?) - fun inject(recentTransactionsFragment: RecentTransactionsFragment?) - fun inject(clientChargeFragment: ClientChargeFragment?) - fun inject(savingAccountsDetailActivity: SavingAccountsDetailFragment?) - fun inject(loanAccountsDetailActivity: LoanAccountsDetailFragment?) - fun inject(accountsFragment: AccountsFragment?) - fun inject(loanAccountSummaryFragment: LoanAccountSummaryFragment?) - fun inject(loanAccountTransactionFragment: LoanAccountTransactionFragment?) - fun inject(loanRepaymentScheduleFragment: LoanRepaymentScheduleFragment?) - fun inject(loanApplicationFragment: LoanApplicationFragment?) - fun inject(loanAccountWithdrawFragment: LoanAccountWithdrawFragment?) - fun inject(savingAccountsTransactionFragment: SavingAccountsTransactionFragment?) - fun inject(savingsMakeTransferFragment: SavingsMakeTransferFragment?) - fun inject(beneficiaryAddOptionsFragment: BeneficiaryAddOptionsFragment?) - fun inject(beneficiaryListFragment: BeneficiaryListFragment?) - fun inject(beneficiaryApplicationFragment: BeneficiaryApplicationFragment?) - fun inject(beneficiaryDetailFragment: BeneficiaryDetailFragment?) - fun inject(thirdPartyTransferFragment: ThirdPartyTransferFragment?) - fun inject(transferProcessFragment: TransferProcessFragment?) - fun inject(userProfileFragment: UserProfileFragment?) - fun inject(helpFragment: HelpFragment?) - fun inject(registrationFragment: RegistrationFragment?) - fun inject(registrationVerificationFragment: RegistrationVerificationFragment?) - fun inject(accountOverviewFragment: AccountOverviewFragment?) - fun inject(homeOldFragment: HomeOldFragment?) - fun inject(notificationFragment: NotificationFragment?) - fun inject(qrCodeImportFragment: QrCodeImportFragment?) - fun inject(splashActivity: SplashActivity?) - fun inject(addGuarantorFragment: AddGuarantorFragment?) - fun inject(guarantorListFragment: GuarantorListFragment?) - fun inject(guarantorDetailFragment: GuarantorDetailFragment?) - fun inject(updatePasswordFragment: UpdatePasswordFragment?) - fun inject(savingsAccountApplicationFragment: SavingsAccountApplicationFragment?) - fun inject(savingsAccountWithdrawFragment: SavingsAccountWithdrawFragment?) - fun inject(reviewLoanApplicationFragment: ReviewLoanApplicationFragment?) - fun inject(qrCodeReaderFragment: QrCodeReaderFragment?) -} diff --git a/app/src/main/java/org/mifos/mobile/injection/component/ApplicationComponent.kt b/app/src/main/java/org/mifos/mobile/injection/component/ApplicationComponent.kt deleted file mode 100644 index 19788b9ae..000000000 --- a/app/src/main/java/org/mifos/mobile/injection/component/ApplicationComponent.kt +++ /dev/null @@ -1,32 +0,0 @@ -package org.mifos.mobile.injection.component - -import android.app.Application -import android.content.Context -import dagger.Component -import dagger.hilt.EntryPoint -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import org.mifos.mobile.api.BaseApiManager -import org.mifos.mobile.api.DataManager -import org.mifos.mobile.api.local.DatabaseHelper -import org.mifos.mobile.api.local.PreferencesHelper -import dagger.hilt.android.qualifiers.ApplicationContext -import org.mifos.mobile.injection.module.ApplicationModule -import javax.inject.Singleton - -/** - * @author ishan - * @since 08/07/16 - */ -@Singleton -@InstallIn(SingletonComponent::class) -@EntryPoint -interface ApplicationComponent { -// @ApplicationContext -// fun context(): Context? -// fun application(): Application? -// fun dataManager(): DataManager? -// fun prefManager(): PreferencesHelper? -// fun baseApiManager(): BaseApiManager? -// fun databaseHelper(): DatabaseHelper? -} diff --git a/app/src/main/java/org/mifos/mobile/injection/module/ApplicationModule.kt b/app/src/main/java/org/mifos/mobile/injection/module/ApplicationModule.kt index 07ceea2cf..0674fa0bd 100644 --- a/app/src/main/java/org/mifos/mobile/injection/module/ApplicationModule.kt +++ b/app/src/main/java/org/mifos/mobile/injection/module/ApplicationModule.kt @@ -1,6 +1,5 @@ package org.mifos.mobile.injection.module -import android.app.Application import android.content.Context import dagger.Module import dagger.Provides @@ -19,17 +18,7 @@ import javax.inject.Singleton */ @Module @InstallIn(SingletonComponent::class) -class ApplicationModule(private val application: Application? = null) { -// @Provides -// fun provideApplication(): Application { -// return application!! -// } - -// @Provides -// @ApplicationContext -// fun provideContext(): Context { -// return application!! -// } +class ApplicationModule() { @Provides @Singleton diff --git a/app/src/main/java/org/mifos/mobile/ui/activities/base/BaseActivity.kt b/app/src/main/java/org/mifos/mobile/ui/activities/base/BaseActivity.kt index 2aa40435f..3a166f66c 100644 --- a/app/src/main/java/org/mifos/mobile/ui/activities/base/BaseActivity.kt +++ b/app/src/main/java/org/mifos/mobile/ui/activities/base/BaseActivity.kt @@ -15,7 +15,6 @@ import androidx.fragment.app.FragmentManager import com.mifos.mobile.passcode.BasePassCodeActivity import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R -import org.mifos.mobile.injection.component.ActivityComponent import org.mifos.mobile.ui.activities.PassCodeActivity import org.mifos.mobile.ui.views.BaseActivityCallback import org.mifos.mobile.utils.LanguageHelper @@ -33,21 +32,6 @@ open class BaseActivity : BasePassCodeActivity(), BaseActivityCallback { var toolbar: Toolbar? = null protected set - /** - * Used for dependency injection - * @return [ActivityComponent] which is used for injection - */ -// var activityComponent: ActivityComponent? = null -// get() { -// if (field == null) { -// field = DaggerActivityComponent.builder() -// .activityModule(ActivityModule(this)) -// .applicationComponent(MifosSelfServiceApp.get(this).component()) -// .build() -// } -// return field -// } -// private set private var progress: ProgressDialog? = null override fun setContentView(layoutResID: Int) { super.setContentView(layoutResID) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/AboutUsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/AboutUsFragment.kt index 177825c1d..1e4fcc866 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/AboutUsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/AboutUsFragment.kt @@ -7,6 +7,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.google.android.gms.oss.licenses.OssLicensesMenuActivity +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.BuildConfig import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentAboutUsBinding @@ -18,6 +19,7 @@ import java.util.Calendar ~This project is licensed under the open source MPL V2. ~See https://github.com/openMF/self-service-app/blob/master/LICENSE.md */ +@AndroidEntryPoint class AboutUsFragment : BaseFragment() { private var _binding: FragmentAboutUsBinding? = null private val binding get() = _binding!! diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/AccountOverviewFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/AccountOverviewFragment.kt index b8894694f..ee787c2b0 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/AccountOverviewFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/AccountOverviewFragment.kt @@ -8,6 +8,7 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentAccountOverviewBinding import org.mifos.mobile.presenters.AccountOverviewPresenter @@ -24,6 +25,7 @@ import javax.inject.Inject * @author Rajan Maurya * On 16/10/17. */ +@AndroidEntryPoint class AccountOverviewFragment : BaseFragment(), AccountOverviewMvpView, OnRefreshListener { private var _binding: FragmentAccountOverviewBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/AccountsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/AccountsFragment.kt index 608f0eadd..4225f15a3 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/AccountsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/AccountsFragment.kt @@ -12,6 +12,7 @@ import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentAccountsBinding import org.mifos.mobile.models.CheckboxStatus @@ -37,6 +38,7 @@ import javax.inject.Inject /** * Created by Rajan Maurya on 23/10/16. */ +@AndroidEntryPoint class AccountsFragment : BaseFragment(), OnRefreshListener, AccountsView { private var _binding: FragmentAccountsBinding? = null private val binding get() = _binding!! diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/AddGuarantorFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/AddGuarantorFragment.kt index aea7859cb..61838a4be 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/AddGuarantorFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/AddGuarantorFragment.kt @@ -7,6 +7,7 @@ import android.view.ViewGroup import android.widget.ArrayAdapter import android.widget.Toast import com.google.android.material.textfield.MaterialAutoCompleteTextView +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentAddGuarantorBinding import org.mifos.mobile.models.guarantor.GuarantorApplicationPayload @@ -27,6 +28,7 @@ import javax.inject.Inject /* * Created by saksham on 23/July/2018 */ +@AndroidEntryPoint class AddGuarantorFragment : BaseFragment(), AddGuarantorView { private var _binding: FragmentAddGuarantorBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryAddOptionsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryAddOptionsFragment.kt index 22146453d..20a84bfd9 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryAddOptionsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryAddOptionsFragment.kt @@ -8,6 +8,7 @@ import android.provider.MediaStore import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentBeneficiaryAddOptionsBinding import org.mifos.mobile.ui.activities.base.BaseActivity @@ -23,6 +24,7 @@ import org.mifos.mobile.utils.Toaster /** * Created by dilpreet on 5/7/17. */ +@AndroidEntryPoint class BeneficiaryAddOptionsFragment : BaseFragment() { private var _binding: FragmentBeneficiaryAddOptionsBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryApplicationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryApplicationFragment.kt index 63264bb61..f5661a256 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryApplicationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryApplicationFragment.kt @@ -6,6 +6,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentBeneficiaryApplicationBinding import org.mifos.mobile.models.beneficiary.Beneficiary @@ -25,6 +26,7 @@ import javax.inject.Inject /** * Created by dilpreet on 16/6/17. */ +@AndroidEntryPoint class BeneficiaryApplicationFragment : BaseFragment(), BeneficiaryApplicationView { private var _binding: FragmentBeneficiaryApplicationBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryDetailFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryDetailFragment.kt index 594e2ac75..43ad25cb0 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryDetailFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryDetailFragment.kt @@ -8,6 +8,7 @@ import android.view.MenuInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentBeneficiaryDetailBinding import org.mifos.mobile.models.beneficiary.Beneficiary @@ -25,6 +26,7 @@ import javax.inject.Inject /** * Created by dilpreet on 15/6/17. */ +@AndroidEntryPoint class BeneficiaryDetailFragment : BaseFragment(), BeneficiaryDetailView { private var _binding: FragmentBeneficiaryDetailBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryListFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryListFragment.kt index 8322866dc..2331130c7 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryListFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryListFragment.kt @@ -11,6 +11,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentBeneficiaryListBinding import org.mifos.mobile.models.beneficiary.Beneficiary @@ -28,6 +29,7 @@ import javax.inject.Inject /** * Created by dilpreet on 14/6/17. */ +@AndroidEntryPoint class BeneficiaryListFragment : BaseFragment(), OnRefreshListener, BeneficiariesView { private var _binding: FragmentBeneficiaryListBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/ClientAccountsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/ClientAccountsFragment.kt index a4cf3774f..300e00488 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/ClientAccountsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/ClientAccountsFragment.kt @@ -20,6 +20,7 @@ import androidx.recyclerview.widget.RecyclerView import androidx.viewpager.widget.ViewPager.OnPageChangeListener import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.tabs.TabLayout +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentClientAccountsBinding import org.mifos.mobile.models.accounts.loan.LoanAccount @@ -42,7 +43,9 @@ 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 -*/ class ClientAccountsFragment : BaseFragment(), AccountsView { +*/ +@AndroidEntryPoint +class ClientAccountsFragment : BaseFragment(), AccountsView { private var _binding: FragmentClientAccountsBinding? = null private val binding get() = _binding!! diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/ClientChargeFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/ClientChargeFragment.kt index f12175318..b0fd354ff 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/ClientChargeFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/ClientChargeFragment.kt @@ -13,6 +13,7 @@ import butterknife.BindView import butterknife.ButterKnife import butterknife.OnClick import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.models.Charge import org.mifos.mobile.presenters.ClientChargePresenter @@ -31,6 +32,7 @@ import javax.inject.Inject * @author Vishwajeet * @since 17/8/16. */ +@AndroidEntryPoint class ClientChargeFragment : BaseFragment(), ClientChargeView { @JvmField diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorDetailFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorDetailFragment.kt index 37e8f6a8a..e8d10e7d2 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorDetailFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorDetailFragment.kt @@ -8,6 +8,7 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import android.widget.Toast +import dagger.hilt.android.AndroidEntryPoint import io.reactivex.disposables.Disposable import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentGuarantorDetailBinding @@ -29,7 +30,9 @@ import javax.inject.Inject /* * Created by saksham on 24/July/2018 -*/ class GuarantorDetailFragment : BaseFragment(), GuarantorDetailView { +*/ +@AndroidEntryPoint +class GuarantorDetailFragment : BaseFragment(), GuarantorDetailView { private var _binding: FragmentGuarantorDetailBinding? = null private val binding get() = _binding!! diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorListFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorListFragment.kt index ad7d878cc..7498c8982 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorListFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorListFragment.kt @@ -6,6 +6,7 @@ import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler +import dagger.hilt.android.AndroidEntryPoint import io.reactivex.disposables.Disposable import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentGuarantorListBinding @@ -26,6 +27,7 @@ import javax.inject.Inject /* * Created by saksham on 23/July/2018 */ +@AndroidEntryPoint class GuarantorListFragment : BaseFragment(), GuarantorListView { private var _binding: FragmentGuarantorListBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/HelpFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/HelpFragment.kt index 057d77df2..4214fd7b2 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/HelpFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/HelpFragment.kt @@ -15,6 +15,7 @@ import android.widget.Toast import androidx.appcompat.widget.SearchView 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 @@ -31,6 +32,7 @@ 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 { private var _binding: FragmentHelpBinding? = null private val binding get() = _binding!! diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountSummaryFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountSummaryFragment.kt index a1ca4a0f9..52411097c 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountSummaryFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountSummaryFragment.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentLoanAccountSummaryBinding import org.mifos.mobile.models.accounts.loan.LoanWithAssociations @@ -18,6 +19,7 @@ import org.mifos.mobile.utils.CurrencyUtil */ /** * Created by dilpreet on 25/2/17. */ +@AndroidEntryPoint class LoanAccountSummaryFragment : BaseFragment() { private var _binding: FragmentLoanAccountSummaryBinding? = null private val binding get() = _binding!! diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt index 08c53973b..5ee43bff3 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt @@ -10,6 +10,7 @@ import android.widget.Toast import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentLoanAccountTransactionsBinding import org.mifos.mobile.models.accounts.loan.LoanWithAssociations @@ -28,6 +29,7 @@ import javax.inject.Inject */ /** * Created by dilpreet on 4/3/17. */ +@AndroidEntryPoint class LoanAccountTransactionFragment : BaseFragment(), LoanAccountsTransactionView { private var _binding: FragmentLoanAccountTransactionsBinding? = null private val binding get() = _binding!! diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt index d5d744f29..2d1abed43 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentLoanWithdrawBinding import org.mifos.mobile.models.accounts.loan.LoanWithAssociations @@ -20,6 +21,7 @@ import javax.inject.Inject /** * Created by dilpreet on 7/6/17. */ +@AndroidEntryPoint class LoanAccountWithdrawFragment : BaseFragment(), LoanAccountWithdrawView { private var _binding: FragmentLoanWithdrawBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt index 0a3fe68d7..46856567c 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt @@ -10,6 +10,7 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.databinding.FragmentLoanAccountDetailsBinding @@ -35,6 +36,7 @@ import javax.inject.Inject * @author Vishwajeet * @since 19/08/16 */ +@AndroidEntryPoint class LoanAccountsDetailFragment : BaseFragment(), LoanAccountsDetailView { private var _binding: FragmentLoanAccountDetailsBinding? = null private val binding get() = _binding!! diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt index 9dfebadf2..49989ea97 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt @@ -6,6 +6,7 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.DialogFragment +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentAddLoanApplicationBinding import org.mifos.mobile.models.accounts.loan.LoanAccount @@ -33,6 +34,7 @@ import javax.inject.Inject /** * Created by Rajan Maurya on 06/03/17. */ +@AndroidEntryPoint class LoanApplicationFragment : BaseFragment(), LoanApplicationMvpView { private var _binding: FragmentAddLoanApplicationBinding? = null private val binding get() = _binding!! diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt index f022482cf..338bf9854 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt @@ -8,6 +8,7 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentLoanRepaymentScheduleBinding import org.mifos.mobile.models.accounts.loan.LoanWithAssociations @@ -28,6 +29,7 @@ import javax.inject.Inject /** * Created by Rajan Maurya on 03/03/17. */ +@AndroidEntryPoint class LoanRepaymentScheduleFragment : BaseFragment(), LoanRepaymentScheduleMvpView { private var _binding: FragmentLoanRepaymentScheduleBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LocationsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LocationsFragment.kt index a49ef8cb2..143dd081b 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LocationsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LocationsFragment.kt @@ -11,6 +11,7 @@ import com.google.android.gms.maps.MapsInitializer import com.google.android.gms.maps.OnMapReadyCallback import com.google.android.gms.maps.model.LatLng import com.google.android.gms.maps.model.MarkerOptions +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentLocationsBinding import org.mifos.mobile.ui.fragments.base.BaseFragment @@ -21,6 +22,7 @@ import org.mifos.mobile.ui.fragments.base.BaseFragment */ /** * Created by dilpreet on 25/2/17. */ +@AndroidEntryPoint class LocationsFragment : BaseFragment(), OnMapReadyCallback { private var _binding: FragmentLocationsBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt index de771aa65..dce360bbf 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt @@ -8,6 +8,7 @@ import android.widget.Toast import androidx.recyclerview.widget.LinearLayoutManager import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.BuildConfig import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentNotificationBinding @@ -24,6 +25,7 @@ import javax.inject.Inject /** * Created by dilpreet on 13/9/17. */ +@AndroidEntryPoint class NotificationFragment : BaseFragment(), NotificationView, OnRefreshListener { private var _binding: FragmentNotificationBinding? = null private val binding get() = _binding!! diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeDisplayFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeDisplayFragment.kt index 36ad48c88..a8f2d966b 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeDisplayFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeDisplayFragment.kt @@ -9,6 +9,7 @@ import android.view.MenuInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentQrCodeDisplayBinding import org.mifos.mobile.ui.fragments.base.BaseFragment @@ -19,6 +20,7 @@ import org.mifos.mobile.utils.Utils /** * Created by dilpreet on 16/8/17. */ +@AndroidEntryPoint class QrCodeDisplayFragment : BaseFragment() { private var _binding: FragmentQrCodeDisplayBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeImportFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeImportFragment.kt index 8b479f0d4..540b874be 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeImportFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeImportFragment.kt @@ -13,6 +13,7 @@ import com.google.gson.Gson import com.google.gson.JsonSyntaxException import com.google.zxing.Result import com.isseiaoki.simplecropview.CropImageView +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentQrCodeImportBinding import org.mifos.mobile.models.beneficiary.Beneficiary @@ -30,6 +31,7 @@ import javax.inject.Inject /** * Created by manishkumar on 19/05/18. */ +@AndroidEntryPoint class QrCodeImportFragment : BaseFragment(), QrCodeImportView { private var _binding: FragmentQrCodeImportBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeReaderFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeReaderFragment.kt index 1682f2308..c211b9760 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeReaderFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeReaderFragment.kt @@ -9,6 +9,7 @@ import android.widget.Toast import com.google.gson.Gson import com.google.gson.JsonSyntaxException import com.google.zxing.Result +import dagger.hilt.android.AndroidEntryPoint import me.dm7.barcodescanner.zxing.ZXingScannerView import me.dm7.barcodescanner.zxing.ZXingScannerView.ResultHandler import org.mifos.mobile.R @@ -21,6 +22,7 @@ import org.mifos.mobile.ui.fragments.base.BaseFragment /** * Created by dilpreet on 6/7/17. */ +@AndroidEntryPoint class QrCodeReaderFragment : BaseFragment(), ResultHandler { private var _binding: FragmentScanQrCodeBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt index e69dc17b3..9dc4adbd5 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt @@ -10,6 +10,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentRecentTransactionsBinding import org.mifos.mobile.models.Transaction @@ -29,6 +30,7 @@ import javax.inject.Inject * @author Vishwwajeet * @since 09/08/16 */ +@AndroidEntryPoint class RecentTransactionsFragment : BaseFragment(), RecentTransactionsView, OnRefreshListener { private var _binding: FragmentRecentTransactionsBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt index 45eb787d1..4fb109820 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt @@ -11,6 +11,7 @@ import android.view.ViewGroup import android.widget.RadioButton import android.widget.TextView import com.hbb20.CountryCodePicker +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentRegistrationBinding import org.mifos.mobile.models.register.RegisterPayload @@ -26,6 +27,7 @@ import javax.inject.Inject /** * Created by dilpreet on 31/7/17. */ +@AndroidEntryPoint class RegistrationFragment : BaseFragment(), RegistrationView { private var _binding: FragmentRegistrationBinding? = null private val binding get() = _binding!! diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt index dec12f98a..22694c865 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt @@ -6,6 +6,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentRegistrationVerificationBinding import org.mifos.mobile.models.register.UserVerify @@ -20,6 +21,7 @@ import javax.inject.Inject /** * Created by dilpreet on 31/7/17. */ +@AndroidEntryPoint class RegistrationVerificationFragment : BaseFragment(), RegistrationVerificationView { private var _binding: FragmentRegistrationVerificationBinding? = null private val binding get() = _binding!! diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt index a8fb2e3a4..fe9f8949e 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt @@ -5,6 +5,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.lifecycle.ViewModelProviders +import dagger.hilt.android.AndroidEntryPoint import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers @@ -32,6 +33,7 @@ import org.mifos.mobile.utils.Network import org.mifos.mobile.utils.Toaster import org.mifos.mobile.viewModels.ReviewLoanApplicationViewModel +@AndroidEntryPoint class ReviewLoanApplicationFragment : BaseFragment() { companion object { diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt index 9c5940643..07cf503de 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt @@ -12,6 +12,7 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.databinding.FragmentSavingAccountDetailsBinding @@ -38,6 +39,7 @@ import javax.inject.Inject * @author Vishwajeet * @since 18/8/16. */ +@AndroidEntryPoint class SavingAccountsDetailFragment : BaseFragment(), SavingAccountsDetailView { private var _binding: FragmentSavingAccountDetailsBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt index ed15c16ac..03b51e352 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt @@ -19,6 +19,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler import com.google.android.material.dialog.MaterialAlertDialogBuilder +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentSavingAccountTransactionsBinding import org.mifos.mobile.models.CheckboxStatus @@ -44,6 +45,7 @@ import javax.inject.Inject /** * Created by dilpreet on 6/3/17. */ +@AndroidEntryPoint class SavingAccountsTransactionFragment : BaseFragment(), SavingAccountsTransactionView { private var _binding: FragmentSavingAccountTransactionsBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountApplicationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountApplicationFragment.kt index c54a11671..20473e089 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountApplicationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountApplicationFragment.kt @@ -5,6 +5,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.databinding.FragmentSavingsAccountApplicationBinding @@ -27,6 +28,7 @@ import javax.inject.Inject /* * Created by saksham on 30/June/2018 */ +@AndroidEntryPoint class SavingsAccountApplicationFragment : BaseFragment(), SavingsAccountApplicationView { private var _binding: FragmentSavingsAccountApplicationBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountWithdrawFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountWithdrawFragment.kt index 510281dfb..b12d5df86 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountWithdrawFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountWithdrawFragment.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentSavingsAccountWithdrawFragmentBinding import org.mifos.mobile.models.accounts.savings.SavingsAccountWithdrawPayload @@ -20,6 +21,7 @@ import javax.inject.Inject /* * Created by saksham on 02/July/2018 */ +@AndroidEntryPoint class SavingsAccountWithdrawFragment : BaseFragment(), SavingsAccountWithdrawView { private var _binding: FragmentSavingsAccountWithdrawFragmentBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsMakeTransferFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsMakeTransferFragment.kt index c4bafec92..10614cf69 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsMakeTransferFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsMakeTransferFragment.kt @@ -11,6 +11,7 @@ import android.view.ViewGroup import android.widget.EditText import android.widget.Spinner import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentSavingsMakeTransferBinding import org.mifos.mobile.models.payload.TransferPayload @@ -33,6 +34,7 @@ import javax.inject.Inject /** * Created by Rajan Maurya on 10/03/17. */ +@AndroidEntryPoint class SavingsMakeTransferFragment : BaseFragment(), SavingsMakeTransferMvpView { private var _binding: FragmentSavingsMakeTransferBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SettingsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SettingsFragment.kt index 5132f6c4b..1f34d3bf5 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SettingsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SettingsFragment.kt @@ -12,6 +12,7 @@ import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.mifos.mobile.passcode.utils.PasscodePreferencesHelper +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.ui.activities.PassCodeActivity @@ -24,6 +25,7 @@ import org.mifos.mobile.utils.LanguageHelper /** * Created by dilpreet on 02/10/17. */ +@AndroidEntryPoint class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListener { private val prefsHelper by lazy { PreferencesHelper(requireContext().applicationContext) } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/ThirdPartyTransferFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/ThirdPartyTransferFragment.kt index 19a5e269e..7c3ec89d7 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/ThirdPartyTransferFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/ThirdPartyTransferFragment.kt @@ -13,6 +13,7 @@ import android.widget.AdapterView.OnItemSelectedListener import android.widget.EditText import android.widget.Spinner import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentThirdPartyTransferBinding import org.mifos.mobile.models.beneficiary.Beneficiary @@ -39,6 +40,7 @@ import javax.inject.Inject /** * Created by dilpreet on 21/6/17. */ +@AndroidEntryPoint class ThirdPartyTransferFragment : BaseFragment(), ThirdPartyTransferView, OnItemSelectedListener { private var _binding: FragmentThirdPartyTransferBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/TransferProcessFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/TransferProcessFragment.kt index be4e255a3..023c768b7 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/TransferProcessFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/TransferProcessFragment.kt @@ -5,6 +5,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentTransferProcessBinding import org.mifos.mobile.models.payload.TransferPayload @@ -23,6 +24,7 @@ import javax.inject.Inject /** * Created by dilpreet on 1/7/17. */ +@AndroidEntryPoint class TransferProcessFragment : BaseFragment(), TransferProcessView { private var _binding: FragmentTransferProcessBinding? = null diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt index 05f5706b8..e7e341554 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt @@ -8,6 +8,7 @@ import android.view.View import android.view.View.OnFocusChangeListener import android.view.ViewGroup import android.widget.Toast +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.databinding.FragmentUpdatePasswordBinding @@ -22,7 +23,9 @@ import javax.inject.Inject /* * Created by saksham on 13/July/2018 -*/ class UpdatePasswordFragment : +*/ +@AndroidEntryPoint +class UpdatePasswordFragment : BaseFragment(), UpdatePasswordView, TextWatcher, diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/UserProfileFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/UserProfileFragment.kt index 63e86a38e..dd5da0d7a 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/UserProfileFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/UserProfileFragment.kt @@ -7,6 +7,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler +import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.databinding.FragmentUserProfileBinding @@ -27,6 +28,7 @@ import javax.inject.Inject /** * Created by dilpreet on 10/7/17. */ +@AndroidEntryPoint class UserProfileFragment : BaseFragment(), UserDetailsView { private var _binding: FragmentUserProfileBinding? = null From a0ea36814bcd04f795653370164531d414df2ef8 Mon Sep 17 00:00:00 2001 From: Pratyush Singh Date: Sun, 2 Jul 2023 11:50:10 +0530 Subject: [PATCH 12/35] feat: removed unused imports and activity module --- .../mobile/injection/module/ActivityModule.kt | 30 ------------------- .../ui/fragments/AccountOverviewFragment.kt | 2 -- .../mobile/ui/fragments/AccountsFragment.kt | 2 -- .../ui/fragments/AddGuarantorFragment.kt | 2 -- .../BeneficiaryAddOptionsFragment.kt | 1 - .../BeneficiaryApplicationFragment.kt | 2 -- .../ui/fragments/BeneficiaryDetailFragment.kt | 1 - .../ui/fragments/BeneficiaryListFragment.kt | 1 - .../ui/fragments/ClientAccountsFragment.kt | 1 - .../ui/fragments/ClientChargeFragment.kt | 2 -- .../ui/fragments/GuarantorDetailFragment.kt | 1 - .../ui/fragments/GuarantorListFragment.kt | 1 - .../mifos/mobile/ui/fragments/HelpFragment.kt | 1 - .../mifos/mobile/ui/fragments/HomeFragment.kt | 1 - .../mobile/ui/fragments/HomeOldFragment.kt | 1 - .../fragments/LoanAccountSummaryFragment.kt | 2 -- .../LoanAccountTransactionFragment.kt | 2 -- .../fragments/LoanAccountWithdrawFragment.kt | 2 -- .../fragments/LoanAccountsDetailFragment.kt | 1 - .../ui/fragments/LoanApplicationFragment.kt | 1 - .../LoanRepaymentScheduleFragment.kt | 2 -- .../ui/fragments/NotificationFragment.kt | 2 -- .../ui/fragments/QrCodeImportFragment.kt | 1 - .../ui/fragments/QrCodeReaderFragment.kt | 1 - .../fragments/RecentTransactionsFragment.kt | 1 - .../ui/fragments/RegistrationFragment.kt | 1 - .../RegistrationVerificationFragment.kt | 2 -- .../ReviewLoanApplicationFragment.kt | 2 -- .../fragments/SavingAccountsDetailFragment.kt | 1 - .../SavingAccountsTransactionFragment.kt | 2 -- .../SavingsAccountApplicationFragment.kt | 2 -- .../SavingsAccountWithdrawFragment.kt | 2 -- .../fragments/SavingsMakeTransferFragment.kt | 1 - .../fragments/ThirdPartyTransferFragment.kt | 1 - .../ui/fragments/TransferProcessFragment.kt | 2 -- .../ui/fragments/UpdatePasswordFragment.kt | 1 - .../ui/fragments/UserProfileFragment.kt | 1 - 37 files changed, 82 deletions(-) delete mode 100644 app/src/main/java/org/mifos/mobile/injection/module/ActivityModule.kt diff --git a/app/src/main/java/org/mifos/mobile/injection/module/ActivityModule.kt b/app/src/main/java/org/mifos/mobile/injection/module/ActivityModule.kt deleted file mode 100644 index f08b838bc..000000000 --- a/app/src/main/java/org/mifos/mobile/injection/module/ActivityModule.kt +++ /dev/null @@ -1,30 +0,0 @@ -package org.mifos.mobile.injection.module - -import android.app.Activity -import android.content.Context -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import dagger.hilt.android.qualifiers.ActivityContext - - - -/** - * @author ishan - * @since 08/07/16 - */ -@Module -@InstallIn(SingletonComponent::class) -class ActivityModule(private val activity: Activity? = null) { -// @Provides -// fun providesActivity(): Activity { -// return activity!! -// } - -// @Provides -// @ActivityContext -// fun providesContext(): Context { -// return activity!! -// } -} diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/AccountOverviewFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/AccountOverviewFragment.kt index ee787c2b0..656e9f1d9 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/AccountOverviewFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/AccountOverviewFragment.kt @@ -12,7 +12,6 @@ import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentAccountOverviewBinding import org.mifos.mobile.presenters.AccountOverviewPresenter -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.ui.views.AccountOverviewMvpView import org.mifos.mobile.utils.Constants @@ -47,7 +46,6 @@ class AccountOverviewFragment : BaseFragment(), AccountOverviewMvpView, OnRefres savedInstanceState: Bundle?, ): View { _binding = FragmentAccountOverviewBinding.inflate(inflater, container, false) - //(activity as BaseActivity?)?.activityComponent?.inject(this) accountOverviewPresenter?.attachView(this) setToolbarTitle(getString(R.string.accounts_overview)) binding.swipeContainer.setColorSchemeResources( diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/AccountsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/AccountsFragment.kt index 4225f15a3..a01c7cbed 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/AccountsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/AccountsFragment.kt @@ -22,7 +22,6 @@ import org.mifos.mobile.models.accounts.share.ShareAccount import org.mifos.mobile.presenters.AccountsPresenter import org.mifos.mobile.ui.activities.LoanAccountContainerActivity import org.mifos.mobile.ui.activities.SavingsAccountContainerActivity -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.adapters.LoanAccountsListAdapter import org.mifos.mobile.ui.adapters.SavingAccountsListAdapter import org.mifos.mobile.ui.adapters.ShareAccountsListAdapter @@ -78,7 +77,6 @@ class AccountsFragment : BaseFragment(), OnRefreshListener, AccountsView { private var sweetUIErrorHandler: SweetUIErrorHandler? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - //(activity as BaseActivity?)?.activityComponent?.inject(this) loanAccounts = ArrayList() savingAccounts = ArrayList() shareAccounts = ArrayList() diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/AddGuarantorFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/AddGuarantorFragment.kt index 61838a4be..10e51467c 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/AddGuarantorFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/AddGuarantorFragment.kt @@ -14,7 +14,6 @@ import org.mifos.mobile.models.guarantor.GuarantorApplicationPayload import org.mifos.mobile.models.guarantor.GuarantorPayload import org.mifos.mobile.models.guarantor.GuarantorTemplatePayload import org.mifos.mobile.presenters.AddGuarantorPresenter -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.enums.GuarantorState import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.ui.views.AddGuarantorView @@ -61,7 +60,6 @@ class AddGuarantorFragment : BaseFragment(), AddGuarantorView { savedInstanceState: Bundle?, ): View { _binding = FragmentAddGuarantorBinding.inflate(inflater, container, false) - //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) if (guarantorState == GuarantorState.CREATE) { setToolbarTitle(getString(R.string.add_guarantor)) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryAddOptionsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryAddOptionsFragment.kt index 20a84bfd9..f7e8aa379 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryAddOptionsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryAddOptionsFragment.kt @@ -39,7 +39,6 @@ class BeneficiaryAddOptionsFragment : BaseFragment() { ): View { _binding = FragmentBeneficiaryAddOptionsBinding.inflate(inflater, container, false) setToolbarTitle(getString(R.string.add_beneficiary)) - //(activity as BaseActivity?)?.activityComponent?.inject(this) return binding.root } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryApplicationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryApplicationFragment.kt index f5661a256..907c5fe7d 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryApplicationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryApplicationFragment.kt @@ -14,7 +14,6 @@ import org.mifos.mobile.models.beneficiary.BeneficiaryPayload import org.mifos.mobile.models.beneficiary.BeneficiaryUpdatePayload import org.mifos.mobile.models.templates.beneficiary.BeneficiaryTemplate import org.mifos.mobile.presenters.BeneficiaryApplicationPresenter -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.enums.BeneficiaryState import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.ui.views.BeneficiaryApplicationView @@ -71,7 +70,6 @@ class BeneficiaryApplicationFragment : BaseFragment(), BeneficiaryApplicationVie savedInstanceState: Bundle?, ): View { _binding = FragmentBeneficiaryApplicationBinding.inflate(inflater, container, false) - //(activity as BaseActivity?)?.activityComponent?.inject(this) sweetUIErrorHandler = SweetUIErrorHandler(activity, binding.root) showUserInterface() presenter?.attachView(this) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryDetailFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryDetailFragment.kt index 43ad25cb0..6f03e85ad 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryDetailFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryDetailFragment.kt @@ -50,7 +50,6 @@ class BeneficiaryDetailFragment : BaseFragment(), BeneficiaryDetailView { savedInstanceState: Bundle?, ): View { _binding = FragmentBeneficiaryDetailBinding.inflate(inflater, container, false) - //(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.beneficiary_detail)) presenter?.attachView(this) showUserInterface() diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryListFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryListFragment.kt index 2331130c7..7baa909be 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryListFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/BeneficiaryListFragment.kt @@ -50,7 +50,6 @@ class BeneficiaryListFragment : BaseFragment(), OnRefreshListener, Beneficiaries ): View { _binding = FragmentBeneficiaryListBinding.inflate(inflater, container, false) beneficiaryListAdapter = BeneficiaryListAdapter(::onItemClick) - ////(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.beneficiaries)) sweetUIErrorHandler = SweetUIErrorHandler(activity, binding.root) showUserInterface() diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/ClientAccountsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/ClientAccountsFragment.kt index 300e00488..0bc56be2a 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/ClientAccountsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/ClientAccountsFragment.kt @@ -74,7 +74,6 @@ class ClientAccountsFragment : BaseFragment(), AccountsView { ): View { _binding = FragmentClientAccountsBinding.inflate(inflater, container, false) val rootView = binding.root - //(activity as BaseActivity?)?.activityComponent?.inject(this) accountsPresenter?.attachView(this) setToolbarTitle(getString(R.string.accounts)) setUpViewPagerAndTabLayout() diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/ClientChargeFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/ClientChargeFragment.kt index b0fd354ff..9b4f00737 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/ClientChargeFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/ClientChargeFragment.kt @@ -17,7 +17,6 @@ import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.models.Charge import org.mifos.mobile.presenters.ClientChargePresenter -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.adapters.ClientChargeAdapter import org.mifos.mobile.ui.enums.ChargeType import org.mifos.mobile.ui.fragments.base.BaseFragment @@ -60,7 +59,6 @@ class ClientChargeFragment : BaseFragment(), ClientChargeView { private var sweetUIErrorHandler: SweetUIErrorHandler? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - //(activity as BaseActivity?)?.activityComponent?.inject(this) if (arguments != null) { id = arguments?.getLong(Constants.CLIENT_ID) chargeType = arguments?.getSerializable(Constants.CHARGE_TYPE) as ChargeType diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorDetailFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorDetailFragment.kt index e8d10e7d2..7902705ce 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorDetailFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorDetailFragment.kt @@ -64,7 +64,6 @@ class GuarantorDetailFragment : BaseFragment(), GuarantorDetailView { _binding = FragmentGuarantorDetailBinding.inflate(inflater, container, false) setToolbarTitle(getString(R.string.guarantor_details)) setHasOptionsMenu(true) - //(activity as BaseActivity?)?.activityComponent?.inject(this) if (isFirstTime) { isFirstTime = false setUpRxBus() diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorListFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorListFragment.kt index 7498c8982..f6ec88bb2 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorListFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/GuarantorListFragment.kt @@ -54,7 +54,6 @@ class GuarantorListFragment : BaseFragment(), GuarantorListView { ): View { _binding = FragmentGuarantorListBinding.inflate(inflater, container, false) setToolbarTitle(getString(R.string.view_guarantor)) - //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) if (list == null) { presenter?.getGuarantorList(loanId) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/HelpFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/HelpFragment.kt index 4214fd7b2..3736a0119 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/HelpFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/HelpFragment.kt @@ -55,7 +55,6 @@ class HelpFragment : BaseFragment(), HelpView { _binding = FragmentHelpBinding.inflate(inflater, container, false) val rootView = binding.root setHasOptionsMenu(true) - //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) setToolbarTitle(getString(R.string.help)) sweetUIErrorHandler = SweetUIErrorHandler(activity, rootView) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/HomeFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/HomeFragment.kt index 86606396e..99602c337 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/HomeFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/HomeFragment.kt @@ -71,7 +71,6 @@ class HomeFragment : BaseFragment(), HomeView, OnRefreshListener { savedInstanceState: Bundle?, ): View { rootView = inflater.inflate(R.layout.fragment_home_ui, container, false) -// (activity as HomeActivity?)?.activityComponent?.inject(this) ButterKnife.bind(this, rootView) clientId = preferencesHelper?.clientId setHasOptionsMenu(true) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt index aabe77c70..f945fea83 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt @@ -74,7 +74,6 @@ class HomeOldFragment : BaseFragment(), HomeOldView, OnRefreshListener { ): View { _binding = FragmentHomeOldBinding.inflate(inflater, container, false) val rootView = binding.root -// (activity as HomeActivity?)?.activityComponent?.inject(this) clientId = preferencesHelper?.clientId presenter?.attachView(this) setHasOptionsMenu(true) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountSummaryFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountSummaryFragment.kt index 52411097c..38e7052fa 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountSummaryFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountSummaryFragment.kt @@ -8,7 +8,6 @@ import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentLoanAccountSummaryBinding import org.mifos.mobile.models.accounts.loan.LoanWithAssociations -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.utils.Constants import org.mifos.mobile.utils.CurrencyUtil @@ -26,7 +25,6 @@ class LoanAccountSummaryFragment : BaseFragment() { private var loanWithAssociations: LoanWithAssociations? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - //(activity as BaseActivity?)?.activityComponent?.inject(this) if (arguments != null) { loanWithAssociations = arguments?.getParcelable(Constants.LOAN_ACCOUNT) } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt index 5ee43bff3..0a53df36b 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt @@ -15,7 +15,6 @@ import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentLoanAccountTransactionsBinding import org.mifos.mobile.models.accounts.loan.LoanWithAssociations import org.mifos.mobile.presenters.LoanAccountsTransactionPresenter -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.adapters.RecentTransactionListAdapter import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.ui.views.LoanAccountsTransactionView @@ -46,7 +45,6 @@ class LoanAccountTransactionFragment : BaseFragment(), LoanAccountsTransactionVi private var sweetUIErrorHandler: SweetUIErrorHandler? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - //(activity as BaseActivity?)?.activityComponent?.inject(this) if (arguments != null) { loanId = arguments?.getLong(Constants.LOAN_ID) } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt index 2d1abed43..93ba7b2f7 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt @@ -10,7 +10,6 @@ import org.mifos.mobile.databinding.FragmentLoanWithdrawBinding import org.mifos.mobile.models.accounts.loan.LoanWithAssociations import org.mifos.mobile.models.accounts.loan.LoanWithdraw import org.mifos.mobile.presenters.LoanAccountWithdrawPresenter -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.ui.views.LoanAccountWithdrawView import org.mifos.mobile.utils.Constants @@ -33,7 +32,6 @@ class LoanAccountWithdrawFragment : BaseFragment(), LoanAccountWithdrawView { private var loanWithAssociations: LoanWithAssociations? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - //(activity as BaseActivity?)?.activityComponent?.inject(this) if (arguments != null) { loanWithAssociations = arguments?.getParcelable(Constants.LOAN_ACCOUNT) } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt index 46856567c..0d9fa83fc 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt @@ -65,7 +65,6 @@ class LoanAccountsDetailFragment : BaseFragment(), LoanAccountsDetailView { container: ViewGroup?, savedInstanceState: Bundle?, ): View { - //(activity as BaseActivity?)?.activityComponent?.inject(this) _binding = FragmentLoanAccountDetailsBinding.inflate(inflater, container, false) val rootView = binding.root setToolbarTitle(getString(R.string.loan_account_details)) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt index 49989ea97..d84d0ee05 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt @@ -101,7 +101,6 @@ class LoanApplicationFragment : BaseFragment(), LoanApplicationMvpView { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - //(activity as BaseActivity?)?.activityComponent?.inject(this) if (arguments != null) { loanState = arguments?.getSerializable(Constants.LOAN_STATE) as LoanState if (loanState == LoanState.CREATE) { diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt index 338bf9854..e7ff3ae82 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt @@ -17,7 +17,6 @@ import org.mifos.mobile.models.accounts.loan.tableview.Cell import org.mifos.mobile.models.accounts.loan.tableview.ColumnHeader import org.mifos.mobile.models.accounts.loan.tableview.RowHeader import org.mifos.mobile.presenters.LoanRepaymentSchedulePresenter -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.adapters.LoanRepaymentScheduleAdapter import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.ui.views.LoanRepaymentScheduleMvpView @@ -47,7 +46,6 @@ class LoanRepaymentScheduleFragment : BaseFragment(), LoanRepaymentScheduleMvpVi private var loanWithAssociations: LoanWithAssociations? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - //(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.loan_repayment_schedule)) if (arguments != null) loanId = arguments?.getLong(Constants.LOAN_ID) } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt index dce360bbf..5174458f0 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt @@ -14,7 +14,6 @@ import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentNotificationBinding import org.mifos.mobile.models.notification.MifosNotification import org.mifos.mobile.presenters.NotificationPresenter -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.adapters.NotificationAdapter import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.ui.views.NotificationView @@ -41,7 +40,6 @@ class NotificationFragment : BaseFragment(), NotificationView, OnRefreshListener override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setToolbarTitle(getString(R.string.notification)) - //(activity as BaseActivity?)?.activityComponent?.inject(this) } override fun onCreateView( diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeImportFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeImportFragment.kt index 540b874be..36cfc4d89 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeImportFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeImportFragment.kt @@ -60,7 +60,6 @@ class QrCodeImportFragment : BaseFragment(), QrCodeImportView { savedInstanceState: Bundle?, ): View { _binding = FragmentQrCodeImportBinding.inflate(inflater, container, false) - //(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.import_qr)) // load the uri setBitmapImage(qrUri) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeReaderFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeReaderFragment.kt index c211b9760..f3f1cc01d 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeReaderFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/QrCodeReaderFragment.kt @@ -37,7 +37,6 @@ class QrCodeReaderFragment : BaseFragment(), ResultHandler { ): View { _binding = FragmentScanQrCodeBinding.inflate(inflater, container, false) setToolbarTitle(getString(R.string.add_beneficiary)) - //(activity as BaseActivity?)?.activityComponent?.inject(this) binding.viewScanner.setAutoFocus(true) binding.btnFlash.setOnClickListener { turnOnFlash() diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt index 9dc4adbd5..33fb7d214 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt @@ -47,7 +47,6 @@ class RecentTransactionsFragment : BaseFragment(), RecentTransactionsView, OnRef private var recentTransactionList: MutableList? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - //(activity as BaseActivity?)?.activityComponent?.inject(this) recentTransactionList = ArrayList() } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt index 4fb109820..458719fde 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt @@ -42,7 +42,6 @@ class RegistrationFragment : BaseFragment(), RegistrationView { ): View { _binding = FragmentRegistrationBinding.inflate(inflater, container, false) val rootView = binding.root - //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) binding.progressBar.visibility = View.GONE binding.passwordStrength.visibility = View.GONE diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt index 22694c865..64252cccb 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt @@ -12,7 +12,6 @@ import org.mifos.mobile.databinding.FragmentRegistrationVerificationBinding import org.mifos.mobile.models.register.UserVerify import org.mifos.mobile.presenters.RegistrationVerificationPresenter import org.mifos.mobile.ui.activities.LoginActivity -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.ui.views.RegistrationVerificationView import org.mifos.mobile.utils.Toaster @@ -36,7 +35,6 @@ class RegistrationVerificationFragment : BaseFragment(), RegistrationVerificatio ): View { _binding = FragmentRegistrationVerificationBinding.inflate(inflater, container, false) val rootView = binding.root - //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) return rootView } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt index fe9f8949e..ff079f930 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/ReviewLoanApplicationFragment.kt @@ -25,7 +25,6 @@ import kotlinx.android.synthetic.main.layout_error.tv_status import okhttp3.ResponseBody import org.mifos.mobile.R import org.mifos.mobile.models.payload.LoansPayload -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.enums.LoanState import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.utils.MFErrorParser @@ -91,7 +90,6 @@ class ReviewLoanApplicationFragment : BaseFragment() { savedInstanceState: Bundle?, ): View { rootView = inflater.inflate(R.layout.fragment_review_loan_application, container, false) -// (activity as BaseActivity).activityComponent?.inject(this) viewModel = ViewModelProviders.of(this) .get(ReviewLoanApplicationViewModel::class.java) val loanState = arguments?.getSerializable(LOAN_STATE) as LoanState diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt index 07cf503de..9a3600b74 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsDetailFragment.kt @@ -70,7 +70,6 @@ class SavingAccountsDetailFragment : BaseFragment(), SavingAccountsDetailView { savedInstanceState: Bundle?, ): View { _binding = FragmentSavingAccountDetailsBinding.inflate(inflater, container, false) - //(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.saving_account_details)) savingAccountsDetailPresenter?.attachView(this) sweetUIErrorHandler = SweetUIErrorHandler(context, binding.root) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt index 03b51e352..d2ac45533 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingAccountsTransactionFragment.kt @@ -26,7 +26,6 @@ import org.mifos.mobile.models.CheckboxStatus import org.mifos.mobile.models.accounts.savings.SavingsWithAssociations import org.mifos.mobile.models.accounts.savings.Transactions import org.mifos.mobile.presenters.SavingAccountsTransactionPresenter -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.adapters.CheckBoxAdapter import org.mifos.mobile.ui.adapters.SavingAccountsTransactionListAdapter import org.mifos.mobile.ui.fragments.base.BaseFragment @@ -78,7 +77,6 @@ class SavingAccountsTransactionFragment : BaseFragment(), SavingAccountsTransact override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) - //(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.saving_account_transactions_details)) if (arguments != null) savingsId = arguments?.getLong(Constants.SAVINGS_ID)!! } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountApplicationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountApplicationFragment.kt index 20473e089..4301378bc 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountApplicationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountApplicationFragment.kt @@ -15,7 +15,6 @@ import org.mifos.mobile.models.accounts.savings.SavingsWithAssociations import org.mifos.mobile.models.templates.savings.ProductOptions import org.mifos.mobile.models.templates.savings.SavingsAccountTemplate import org.mifos.mobile.presenters.SavingsAccountApplicationPresenter -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.enums.SavingsAccountState import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.ui.views.SavingsAccountApplicationView @@ -61,7 +60,6 @@ class SavingsAccountApplicationFragment : BaseFragment(), SavingsAccountApplicat savedInstanceState: Bundle?, ): View { _binding = FragmentSavingsAccountApplicationBinding.inflate(inflater) - //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) presenter?.loadSavingsAccountApplicationTemplate(preferencesHelper?.clientId, state) return binding.root diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountWithdrawFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountWithdrawFragment.kt index b12d5df86..a2159d1c7 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountWithdrawFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsAccountWithdrawFragment.kt @@ -10,7 +10,6 @@ import org.mifos.mobile.databinding.FragmentSavingsAccountWithdrawFragmentBindin import org.mifos.mobile.models.accounts.savings.SavingsAccountWithdrawPayload import org.mifos.mobile.models.accounts.savings.SavingsWithAssociations import org.mifos.mobile.presenters.SavingsAccountWithdrawPresenter -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.ui.views.SavingsAccountWithdrawView import org.mifos.mobile.utils.Constants @@ -45,7 +44,6 @@ class SavingsAccountWithdrawFragment : BaseFragment(), SavingsAccountWithdrawVie savedInstanceState: Bundle?, ): View { _binding = FragmentSavingsAccountWithdrawFragmentBinding.inflate(inflater, container, false) - //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) showUserInterface() return binding.root diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsMakeTransferFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsMakeTransferFragment.kt index 10614cf69..1acb402f7 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsMakeTransferFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/SavingsMakeTransferFragment.kt @@ -74,7 +74,6 @@ class SavingsMakeTransferFragment : BaseFragment(), SavingsMakeTransferMvpView { savedInstanceState: Bundle?, ): View { _binding = FragmentSavingsMakeTransferBinding.inflate(inflater, container, false) - //(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.transfer)) savingsMakeTransferPresenter?.attachView(this) sweetUIErrorHandler = SweetUIErrorHandler(activity, binding.root) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/ThirdPartyTransferFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/ThirdPartyTransferFragment.kt index 7c3ec89d7..3b2ff635d 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/ThirdPartyTransferFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/ThirdPartyTransferFragment.kt @@ -69,7 +69,6 @@ class ThirdPartyTransferFragment : BaseFragment(), ThirdPartyTransferView, OnIte container: ViewGroup?, savedInstanceState: Bundle?, ): View { - //(activity as BaseActivity?)?.activityComponent?.inject(this) _binding = FragmentThirdPartyTransferBinding.inflate(inflater, container, false) setToolbarTitle(getString(R.string.third_party_transfer)) sweetUIErrorHandler = SweetUIErrorHandler(activity, binding.root) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/TransferProcessFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/TransferProcessFragment.kt index 023c768b7..c9fa4b825 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/TransferProcessFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/TransferProcessFragment.kt @@ -11,7 +11,6 @@ import org.mifos.mobile.databinding.FragmentTransferProcessBinding import org.mifos.mobile.models.payload.TransferPayload import org.mifos.mobile.presenters.TransferProcessPresenter import org.mifos.mobile.ui.activities.SavingsAccountContainerActivity -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.enums.TransferType import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.ui.views.TransferProcessView @@ -49,7 +48,6 @@ class TransferProcessFragment : BaseFragment(), TransferProcessView { savedInstanceState: Bundle?, ): View { _binding = FragmentTransferProcessBinding.inflate(inflater, container, false) - //(activity as BaseActivity?)?.activityComponent?.inject(this) setToolbarTitle(getString(R.string.transfer)) presenter?.attachView(this) binding.tvAmount.text = CurrencyUtil.formatCurrency(activity, payload?.transferAmount) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt index e7e341554..5ab5f2152 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt @@ -52,7 +52,6 @@ class UpdatePasswordFragment : ): View { _binding = FragmentUpdatePasswordBinding.inflate(inflater, container, false) setToolbarTitle(getString(R.string.change_password)) - //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) binding.tilNewPassword.editText?.addTextChangedListener(this) binding.tilConfirmNewPassword.editText?.addTextChangedListener(this) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/UserProfileFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/UserProfileFragment.kt index dd5da0d7a..71e613c7f 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/UserProfileFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/UserProfileFragment.kt @@ -50,7 +50,6 @@ class UserProfileFragment : BaseFragment(), UserDetailsView { savedInstanceState: Bundle?, ): View { _binding = FragmentUserProfileBinding.inflate(inflater, container, false) - //(activity as BaseActivity?)?.activityComponent?.inject(this) presenter?.attachView(this) (activity as BaseActivity?)?.setSupportActionBar(binding.toolbar) // check this part before pushing (activity as BaseActivity?)?.supportActionBar?.setDisplayHomeAsUpEnabled(true) From f2f8c7e0712f91484aae51dc9774ccf4b86369e3 Mon Sep 17 00:00:00 2001 From: Pratyush Singh Date: Sun, 2 Jul 2023 11:54:36 +0530 Subject: [PATCH 13/35] feat: app level build gradle refactoring --- app/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 405147247..c17867d41 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,7 +20,6 @@ android { // A test runner provided by https://code.google.com/p/android-test-kit/ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true - javaCompileOptions.annotationProcessorOptions.arguments['dagger.hilt.disableModulesHaveInstallInCheck'] = 'true' ndk { abiFilters "armeabi-v7a", "x86", "x86_64", "arm64-v8a" From e54c1f66e5ee5735399e3c55ba29aeacd6a00ea7 Mon Sep 17 00:00:00 2001 From: Pratyush Singh Date: Sun, 2 Jul 2023 21:07:29 +0530 Subject: [PATCH 14/35] feat: removed unused imports from activities --- app/src/main/java/org/mifos/mobile/ui/activities/HomeActivity.kt | 1 - .../main/java/org/mifos/mobile/ui/activities/LoginActivity.kt | 1 - .../main/java/org/mifos/mobile/ui/activities/SplashActivity.kt | 1 - 3 files changed, 3 deletions(-) diff --git a/app/src/main/java/org/mifos/mobile/ui/activities/HomeActivity.kt b/app/src/main/java/org/mifos/mobile/ui/activities/HomeActivity.kt index 980fef106..0db7723d4 100644 --- a/app/src/main/java/org/mifos/mobile/ui/activities/HomeActivity.kt +++ b/app/src/main/java/org/mifos/mobile/ui/activities/HomeActivity.kt @@ -80,7 +80,6 @@ class HomeActivity : public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityHomeBinding.inflate(layoutInflater) - //activityComponent?.inject(this) setContentView(binding.root) clientId = preferencesHelper?.clientId setupNavigationBar() diff --git a/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt b/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt index 064aeb5e4..d76b27117 100644 --- a/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt +++ b/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt @@ -34,7 +34,6 @@ class LoginActivity : BaseActivity(), LoginView { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityLoginBinding.inflate(layoutInflater) - //activityComponent?.inject(this) setContentView(binding.root) loginPresenter?.attachView(this) dismissSoftKeyboardOnBkgTap(binding.nsvBackground) diff --git a/app/src/main/java/org/mifos/mobile/ui/activities/SplashActivity.kt b/app/src/main/java/org/mifos/mobile/ui/activities/SplashActivity.kt index 7117c87e4..0bae7c94b 100644 --- a/app/src/main/java/org/mifos/mobile/ui/activities/SplashActivity.kt +++ b/app/src/main/java/org/mifos/mobile/ui/activities/SplashActivity.kt @@ -17,7 +17,6 @@ class SplashActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { val intent: Intent? super.onCreate(savedInstanceState) - //activityComponent?.inject(this) passcodePreferencesHelper = PasscodePreferencesHelper(this) if (passcodePreferencesHelper?.passCode?.isNotEmpty() == true) { intent = Intent(this, PassCodeActivity::class.java) From 3aa41952d6474e8ca99c3940f7780f58b0637ab9 Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Sun, 2 Jul 2023 10:08:22 +0530 Subject: [PATCH 15/35] feat : registration fragment MVVM migration 1. code reformat 2. injected userAuthRepository interface dependency instead of userAuthRepositoryImp. 3. making dataManager and userAuthRespository as non-nullable. 4. using val instead of var for dependencies. --- .../injection/component/ActivityComponent.kt | 3 +- .../component/ApplicationComponent.kt | 2 +- .../injection/module/RepositoryModule.kt | 16 ++++++ .../mobile/repositories/UserAuthRepository.kt | 13 ++++- .../repositories/UserAuthRepositoryImp.kt | 15 +++-- .../ui/fragments/RegistrationFragment.kt | 32 +++++++---- .../mifos/mobile/utils/RegistrationUiState.kt | 2 +- .../viewModels/RegistrationViewModel.kt | 44 ++++++++++----- .../RegistrationViewModelFactory.kt | 6 +- .../repositories/UserAuthRepositoryImpTest.kt | 40 +++++++++----- .../viewModels/RegistrationViewModelTest.kt | 55 ++++++++++++++----- 11 files changed, 160 insertions(+), 68 deletions(-) create mode 100644 app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt diff --git a/app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt b/app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt index 5fb96e011..a2450e6c4 100644 --- a/app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt +++ b/app/src/main/java/org/mifos/mobile/injection/component/ActivityComponent.kt @@ -3,6 +3,7 @@ package org.mifos.mobile.injection.component import dagger.Component import org.mifos.mobile.injection.PerActivity import org.mifos.mobile.injection.module.ActivityModule +import org.mifos.mobile.injection.module.RepositoryModule import org.mifos.mobile.ui.activities.HomeActivity import org.mifos.mobile.ui.activities.LoginActivity import org.mifos.mobile.ui.activities.PassCodeActivity @@ -49,7 +50,7 @@ import org.mifos.mobile.ui.fragments.UserProfileFragment * @since 08/07/16 */ @PerActivity -@Component(dependencies = [ApplicationComponent::class], modules = [ActivityModule::class]) +@Component(dependencies = [ApplicationComponent::class], modules = [ActivityModule::class, RepositoryModule::class]) interface ActivityComponent { fun inject(loginActivity: LoginActivity?) fun inject(homeActivity: HomeActivity?) diff --git a/app/src/main/java/org/mifos/mobile/injection/component/ApplicationComponent.kt b/app/src/main/java/org/mifos/mobile/injection/component/ApplicationComponent.kt index b6982275c..8ca64117e 100644 --- a/app/src/main/java/org/mifos/mobile/injection/component/ApplicationComponent.kt +++ b/app/src/main/java/org/mifos/mobile/injection/component/ApplicationComponent.kt @@ -21,7 +21,7 @@ interface ApplicationComponent { @ApplicationContext fun context(): Context? fun application(): Application? - fun dataManager(): DataManager? + fun dataManager(): DataManager fun prefManager(): PreferencesHelper? fun baseApiManager(): BaseApiManager? fun databaseHelper(): DatabaseHelper? diff --git a/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt new file mode 100644 index 000000000..a45832fbf --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt @@ -0,0 +1,16 @@ +package org.mifos.mobile.injection.module + +import dagger.Module +import dagger.Provides +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.repositories.UserAuthRepository +import org.mifos.mobile.repositories.UserAuthRepositoryImp + +@Module +class RepositoryModule { + + @Provides + fun providesUserAuthRepository(dataManager: DataManager): UserAuthRepository { + return UserAuthRepositoryImp(dataManager) + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt index b052f330c..145c251ef 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt @@ -5,7 +5,14 @@ import okhttp3.ResponseBody interface UserAuthRepository { - fun registerUser(accountNumber: String?, authenticationMode: String?, email: String?, - firstName: String?, lastName: String?, mobileNumber: String?, password: String?, username: String?) - : Observable? + fun registerUser( + accountNumber: String?, + authenticationMode: String?, + email: String?, + firstName: String?, + lastName: String?, + mobileNumber: String?, + password: String?, + username: String? + ): Observable? } diff --git a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt index ed93e240f..27f45872d 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt @@ -6,14 +6,19 @@ import org.mifos.mobile.api.DataManager import org.mifos.mobile.models.register.RegisterPayload import javax.inject.Inject -class UserAuthRepositoryImp @Inject constructor(private var dataManager : DataManager?) : +class UserAuthRepositoryImp @Inject constructor(private val dataManager: DataManager) : UserAuthRepository { override fun registerUser( - accountNumber: String?, authenticationMode: String?, email: String?, - firstName: String?, lastName: String?, mobileNumber: String?, password: String?, + accountNumber: String?, + authenticationMode: String?, + email: String?, + firstName: String?, + lastName: String?, + mobileNumber: String?, + password: String?, username: String? - ) : Observable? { + ): Observable? { val registerPayload = RegisterPayload().apply { this.accountNumber = accountNumber this.authenticationMode = authenticationMode @@ -24,6 +29,6 @@ class UserAuthRepositoryImp @Inject constructor(private var dataManager : DataMa this.password = password this.username = username } - return dataManager?.registerUser(registerPayload) + return dataManager.registerUser(registerPayload) } } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt index caedf7d53..72d243711 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt @@ -30,7 +30,7 @@ import javax.inject.Inject class RegistrationFragment : BaseFragment() { private var _binding: FragmentRegistrationBinding? = null private val binding get() = _binding!! - private lateinit var viewModel : RegistrationViewModel + private lateinit var viewModel: RegistrationViewModel @Inject lateinit var viewModelFactory: RegistrationViewModelFactory @@ -46,7 +46,11 @@ class RegistrationFragment : BaseFragment() { viewModel = ViewModelProvider(this, viewModelFactory)[RegistrationViewModel::class.java] with(binding) { etPassword.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int ) {} + override fun beforeTextChanged( + charSequence: CharSequence, i: Int, i1: Int, i2: Int + ) { + } + override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) { if (charSequence.isEmpty()) { progressBar.visibility = View.GONE @@ -57,6 +61,7 @@ class RegistrationFragment : BaseFragment() { updatePasswordStrengthView(charSequence.toString()) } } + override fun afterTextChanged(editable: Editable) {} }) } @@ -76,7 +81,7 @@ class RegistrationFragment : BaseFragment() { passwordStrength.setTextColor(str.color) val mode = PorterDuff.Mode.SRC_IN progressBar.progressDrawable?.setColorFilter(str.color, mode) - when(str.getText(context)) { + when (str.getText(context)) { getString(R.string.password_strength_weak) -> progressBar.progress = 25 getString(R.string.password_strength_medium) -> progressBar.progress = 50 getString(R.string.password_strength_strong) -> progressBar.progress = 75 @@ -87,9 +92,9 @@ class RegistrationFragment : BaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + viewModel.registrationUiState.observe(viewLifecycleOwner) { state -> - when(state) { + when (state) { RegistrationUiState.Loading -> showProgress() RegistrationUiState.RegistrationSuccessful -> { @@ -121,7 +126,7 @@ class RegistrationFragment : BaseFragment() { val firstName = etFirstName.text.toString() val lastName = etLastName.text.toString() val mobileNumber = - countryCodePicker.selectedCountryCode.toString() + etPhoneNumber.text.toString() + countryCodePicker.selectedCountryCode.toString() + etPhoneNumber.text.toString() if (etPassword.text.toString() != etConfirmPassword.text.toString()) { Toaster.show(root, getString(R.string.error_password_not_match)) return @@ -130,8 +135,16 @@ class RegistrationFragment : BaseFragment() { val username = etUsername.text.toString().replace(" ", "") if (Network.isConnected(context)) { - viewModel.registerUser(accountNumber, authenticationMode, email, firstName, - lastName, mobileNumber, password, username) + viewModel.registerUser( + accountNumber, + authenticationMode, + email, + firstName, + lastName, + mobileNumber, + password, + username + ) } else { Toaster.show(root, getString(R.string.no_internet_connection)) } @@ -147,8 +160,7 @@ class RegistrationFragment : BaseFragment() { Toaster.show( rootView, getString( - R.string.error_validation_blank, - getString(R.string.account_number) + R.string.error_validation_blank, getString(R.string.account_number) ), ) false diff --git a/app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt b/app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt index 8f865a3fe..a380f5222 100644 --- a/app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt +++ b/app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt @@ -1,7 +1,7 @@ package org.mifos.mobile.utils sealed class RegistrationUiState { - data class ErrorOnRegistration(val exception : Throwable) : RegistrationUiState() + data class ErrorOnRegistration(val exception: Throwable) : RegistrationUiState() object RegistrationSuccessful : RegistrationUiState() object Loading : RegistrationUiState() } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt index 9dd0c042d..8214820cd 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt @@ -9,44 +9,58 @@ import io.reactivex.disposables.CompositeDisposable import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody -import org.mifos.mobile.repositories.UserAuthRepositoryImp +import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.utils.RegistrationUiState import javax.inject.Inject -class RegistrationViewModel @Inject constructor(private var userAuthRepositoryImp: UserAuthRepositoryImp?) : ViewModel() { +class RegistrationViewModel @Inject constructor(private val userAuthRepositoryImp: UserAuthRepository) : + ViewModel() { private val compositeDisposables: CompositeDisposable = CompositeDisposable() private val _registrationUiState = MutableLiveData() - val registrationUiState : LiveData get() = _registrationUiState + val registrationUiState: LiveData get() = _registrationUiState - fun isInputFieldBlank(fieldText : String) : Boolean { + fun isInputFieldBlank(fieldText: String): Boolean { return fieldText.trim().isEmpty() } - fun isInputLengthInadequate(fieldText : String) : Boolean { + fun isInputLengthInadequate(fieldText: String): Boolean { return fieldText.trim().length < 6 } - fun inputHasSpaces(fieldText: String) : Boolean { + fun inputHasSpaces(fieldText: String): Boolean { return fieldText.trim().contains(" ") } - fun hasLeadingTrailingSpaces(fieldText: String) : Boolean { + fun hasLeadingTrailingSpaces(fieldText: String): Boolean { return fieldText.trim().length < fieldText.length } - fun isEmailInvalid(emailText : String) : Boolean { + fun isEmailInvalid(emailText: String): Boolean { return !PatternsCompat.EMAIL_ADDRESS.matcher(emailText.trim()).matches() } - fun registerUser(accountNumber: String, authenticationMode: String, email: String, - firstName: String, lastName: String, mobileNumber: String, password: String, - username: String) { + fun registerUser( + accountNumber: String, + authenticationMode: String, + email: String, + firstName: String, + lastName: String, + mobileNumber: String, + password: String, + username: String + ) { _registrationUiState.value = RegistrationUiState.Loading - userAuthRepositoryImp?.registerUser(accountNumber, authenticationMode, email, firstName, - lastName, mobileNumber, password, username) - ?.observeOn(AndroidSchedulers.mainThread()) - ?.subscribeOn(Schedulers.io()) + userAuthRepositoryImp.registerUser( + accountNumber, + authenticationMode, + email, + firstName, + lastName, + mobileNumber, + password, + username + )?.observeOn(AndroidSchedulers.mainThread())?.subscribeOn(Schedulers.io()) ?.subscribeWith(object : DisposableObserver() { override fun onComplete() {} override fun onError(e: Throwable) { diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt index b01902d1b..9c072e354 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt @@ -2,16 +2,16 @@ package org.mifos.mobile.viewModels import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import org.mifos.mobile.repositories.UserAuthRepositoryImp import org.mifos.mobile.injection.PerActivity +import org.mifos.mobile.repositories.UserAuthRepository import javax.inject.Inject @PerActivity -class RegistrationViewModelFactory @Inject constructor(private val userAuthRepositoryImp: UserAuthRepositoryImp?) : +class RegistrationViewModelFactory @Inject constructor(private val userAuthRepositoryImp: UserAuthRepository) : ViewModelProvider.Factory { override fun create(modelClass: Class): T { - if(modelClass.isAssignableFrom(RegistrationViewModel::class.java)) { + if (modelClass.isAssignableFrom(RegistrationViewModel::class.java)) { return RegistrationViewModel(userAuthRepositoryImp) as T } throw IllegalArgumentException("Unknown ViewModel class: " + modelClass.name) diff --git a/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt b/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt index 93c7ce0fd..bd2b68744 100644 --- a/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt +++ b/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt @@ -2,7 +2,6 @@ package org.mifos.mobile.repositories import io.reactivex.Observable import okhttp3.ResponseBody -import org.junit.After import org.junit.Assert import org.junit.Before import org.junit.Test @@ -18,7 +17,7 @@ import org.mockito.junit.MockitoJUnitRunner class UserAuthRepositoryImpTest { @Mock - lateinit var dataManager : DataManager + lateinit var dataManager: DataManager private lateinit var userAuthRepositoryImp: UserAuthRepositoryImp @@ -30,7 +29,8 @@ class UserAuthRepositoryImpTest { @Test fun testRegisterUser_SuccessResponseReceivedFromDataManager_ReturnSuccessfulRegistration() { - val successResponse : Observable = Observable.just(Mockito.mock(ResponseBody::class.java)) + val successResponse: Observable = + Observable.just(Mockito.mock(ResponseBody::class.java)) val registerPayload = RegisterPayload().apply { this.accountNumber = "accountNumber" this.authenticationMode = "authenticationMode" @@ -42,12 +42,18 @@ class UserAuthRepositoryImpTest { this.username = "username" } - Mockito.`when`(dataManager.registerUser(registerPayload)) - .thenReturn(successResponse) + Mockito.`when`(dataManager.registerUser(registerPayload)).thenReturn(successResponse) - val result = userAuthRepositoryImp.registerUser(registerPayload.accountNumber, - registerPayload.authenticationMode, registerPayload.email, registerPayload.firstName, - registerPayload.lastName, registerPayload.mobileNumber, registerPayload.password, registerPayload.username) + val result = userAuthRepositoryImp.registerUser( + registerPayload.accountNumber, + registerPayload.authenticationMode, + registerPayload.email, + registerPayload.firstName, + registerPayload.lastName, + registerPayload.mobileNumber, + registerPayload.password, + registerPayload.username + ) Mockito.verify(dataManager).registerUser(registerPayload) Assert.assertEquals(result, successResponse) @@ -55,7 +61,7 @@ class UserAuthRepositoryImpTest { @Test fun testRegisterUser_ErrorResponseReceivedFromDataManager_ReturnsUnsuccessfulRegistration() { - val error : Observable = Observable.error(Throwable("Registration Failed")) + val error: Observable = Observable.error(Throwable("Registration Failed")) val registerPayload = RegisterPayload().apply { this.accountNumber = "accountNumber" this.authenticationMode = "authenticationMode" @@ -67,12 +73,18 @@ class UserAuthRepositoryImpTest { this.username = "username" } - Mockito.`when`(dataManager.registerUser(registerPayload)) - .thenReturn(error) + Mockito.`when`(dataManager.registerUser(registerPayload)).thenReturn(error) - val result = userAuthRepositoryImp.registerUser(registerPayload.accountNumber, - registerPayload.authenticationMode, registerPayload.email, registerPayload.firstName, - registerPayload.lastName, registerPayload.mobileNumber, registerPayload.password, registerPayload.username) + val result = userAuthRepositoryImp.registerUser( + registerPayload.accountNumber, + registerPayload.authenticationMode, + registerPayload.email, + registerPayload.firstName, + registerPayload.lastName, + registerPayload.mobileNumber, + registerPayload.password, + registerPayload.username + ) Mockito.verify(dataManager).registerUser(registerPayload) Assert.assertEquals(result, error) diff --git a/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt index aa7567275..63d0f6d64 100644 --- a/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt +++ b/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt @@ -30,7 +30,7 @@ class RegistrationViewModelTest { val rule = InstantTaskExecutorRule() @Mock - lateinit var userAuthRepositoryImp : UserAuthRepositoryImp + lateinit var userAuthRepositoryImp: UserAuthRepositoryImp @Mock lateinit var registrationUiStateObserver: Observer @@ -109,17 +109,27 @@ class RegistrationViewModelTest { fun testRegisterUser_SuccessfulRegistrationReceivedFromRepository_ReturnsRegistrationSuccessful() { val responseBody = Mockito.mock(ResponseBody::class.java) Mockito.`when`( - userAuthRepositoryImp.registerUser(Mockito.anyString(), Mockito.anyString(), + userAuthRepositoryImp.registerUser( + Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), - Mockito.anyString(), Mockito.anyString(),) - ).thenReturn(Observable.just(responseBody)) - - registrationViewModel.registerUser("accountNumber", "authMode", - "email", "firstName", "lastName", "mobileNumber", "password" - , "userName") + Mockito.anyString(), Mockito.anyString(), + ) + ).thenReturn(Observable.just(responseBody)) + + registrationViewModel.registerUser( + "accountNumber", + "authMode", + "email", + "firstName", + "lastName", + "mobileNumber", + "password", + "userName" + ) Mockito.verify(registrationUiStateObserver).onChanged(RegistrationUiState.Loading) - Mockito.verify(registrationUiStateObserver).onChanged(RegistrationUiState.RegistrationSuccessful) + Mockito.verify(registrationUiStateObserver) + .onChanged(RegistrationUiState.RegistrationSuccessful) Mockito.verifyNoMoreInteractions(registrationUiStateObserver) } @@ -128,16 +138,31 @@ class RegistrationViewModelTest { val error = RuntimeException("Registration Failed") Mockito.`when`( userAuthRepositoryImp.registerUser( - Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), - Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()) + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyString(), + Mockito.anyString() + ) ).thenReturn(Observable.error(error)) - registrationViewModel.registerUser("accountNumber", - "authMode", "email", "firstName", "lastName", - "mobileNumber", "password", "username") + registrationViewModel.registerUser( + "accountNumber", + "authMode", + "email", + "firstName", + "lastName", + "mobileNumber", + "password", + "username" + ) Mockito.verify(registrationUiStateObserver).onChanged(RegistrationUiState.Loading) - Mockito.verify(registrationUiStateObserver).onChanged(RegistrationUiState.ErrorOnRegistration(error)) + Mockito.verify(registrationUiStateObserver) + .onChanged(RegistrationUiState.ErrorOnRegistration(error)) Mockito.verifyNoMoreInteractions(registrationUiStateObserver) } From a2038b4b2d4edf9a247bb0f940cceffe43b9ba8c Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Tue, 4 Jul 2023 00:10:14 +0530 Subject: [PATCH 16/35] fix : Registration fragment MVVM migration resolved conflicts --- .../injection/module/RepositoryModule.kt | 3 +++ .../ui/fragments/RegistrationFragment.kt | 8 +------- .../viewModels/RegistrationViewModel.kt | 2 ++ .../RegistrationViewModelFactory.kt | 19 ------------------- 4 files changed, 6 insertions(+), 26 deletions(-) delete mode 100644 app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt diff --git a/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt index a45832fbf..2063047cc 100644 --- a/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt +++ b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt @@ -2,11 +2,14 @@ package org.mifos.mobile.injection.module import dagger.Module import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent import org.mifos.mobile.api.DataManager import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.repositories.UserAuthRepositoryImp @Module +@InstallIn(SingletonComponent::class) class RepositoryModule { @Provides diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt index 6ee8112c6..889047a32 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt @@ -22,8 +22,6 @@ import org.mifos.mobile.utils.PasswordStrength import org.mifos.mobile.utils.RegistrationUiState import org.mifos.mobile.utils.Toaster import org.mifos.mobile.viewModels.RegistrationViewModel -import org.mifos.mobile.viewModels.RegistrationViewModelFactory -import javax.inject.Inject /** * Created by dilpreet on 31/7/17. @@ -34,9 +32,6 @@ class RegistrationFragment : BaseFragment() { private val binding get() = _binding!! private lateinit var viewModel: RegistrationViewModel - @Inject - lateinit var viewModelFactory: RegistrationViewModelFactory - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -44,8 +39,7 @@ class RegistrationFragment : BaseFragment() { ): View { _binding = FragmentRegistrationBinding.inflate(inflater, container, false) val rootView = binding.root - (activity as BaseActivity?)?.activityComponent?.inject(this) - viewModel = ViewModelProvider(this, viewModelFactory)[RegistrationViewModel::class.java] + viewModel = ViewModelProvider(this)[RegistrationViewModel::class.java] with(binding) { etPassword.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged( diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt index 8214820cd..f773d8d9f 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt @@ -4,6 +4,7 @@ import androidx.core.util.PatternsCompat import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.observers.DisposableObserver @@ -13,6 +14,7 @@ import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.utils.RegistrationUiState import javax.inject.Inject +@HiltViewModel class RegistrationViewModel @Inject constructor(private val userAuthRepositoryImp: UserAuthRepository) : ViewModel() { private val compositeDisposables: CompositeDisposable = CompositeDisposable() diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt deleted file mode 100644 index 9c072e354..000000000 --- a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModelFactory.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.mifos.mobile.viewModels - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import org.mifos.mobile.injection.PerActivity -import org.mifos.mobile.repositories.UserAuthRepository -import javax.inject.Inject - -@PerActivity -class RegistrationViewModelFactory @Inject constructor(private val userAuthRepositoryImp: UserAuthRepository) : - ViewModelProvider.Factory { - - override fun create(modelClass: Class): T { - if (modelClass.isAssignableFrom(RegistrationViewModel::class.java)) { - return RegistrationViewModel(userAuthRepositoryImp) as T - } - throw IllegalArgumentException("Unknown ViewModel class: " + modelClass.name) - } -} \ No newline at end of file From 3d2c4ecbf411e514085a79a251c8f938bd6b4a3c Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Tue, 4 Jul 2023 12:22:58 +0530 Subject: [PATCH 17/35] fix : Notification Fragment migration to MVVM 1. Fixed Merge Conflicts 2. Fix for build fail --- .../mifos/mobile/NotificationRepository.kt | 12 ------------ .../injection/module/RepositoryModule.kt | 7 +++++++ .../repositories/NotificationRepository.kt | 9 +++++++++ .../repositories/NotificationRepositoryImp.kt | 12 ++++++++++++ .../ui/fragments/NotificationFragment.kt | 7 +------ .../viewModels/NotificationViewModel.kt | 10 ++++++---- .../NotificationViewModelFactory.kt | 19 ------------------- 7 files changed, 35 insertions(+), 41 deletions(-) delete mode 100644 app/src/main/java/org/mifos/mobile/NotificationRepository.kt create mode 100644 app/src/main/java/org/mifos/mobile/repositories/NotificationRepository.kt create mode 100644 app/src/main/java/org/mifos/mobile/repositories/NotificationRepositoryImp.kt delete mode 100644 app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModelFactory.kt diff --git a/app/src/main/java/org/mifos/mobile/NotificationRepository.kt b/app/src/main/java/org/mifos/mobile/NotificationRepository.kt deleted file mode 100644 index ae826210d..000000000 --- a/app/src/main/java/org/mifos/mobile/NotificationRepository.kt +++ /dev/null @@ -1,12 +0,0 @@ -package org.mifos.mobile - -import io.reactivex.Observable -import org.mifos.mobile.api.DataManager -import org.mifos.mobile.models.notification.MifosNotification - -class NotificationRepository(private val dataManager: DataManager?) { - - fun loadNotifications() : Observable?>? { - return dataManager?.notifications - } -} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt index 2063047cc..92abe7dbd 100644 --- a/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt +++ b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt @@ -4,7 +4,9 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent +import org.mifos.mobile.repositories.NotificationRepositoryImp import org.mifos.mobile.api.DataManager +import org.mifos.mobile.repositories.NotificationRepository import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.repositories.UserAuthRepositoryImp @@ -16,4 +18,9 @@ class RepositoryModule { fun providesUserAuthRepository(dataManager: DataManager): UserAuthRepository { return UserAuthRepositoryImp(dataManager) } + + @Provides + fun providesNotificationRepository(dataManager: DataManager) : NotificationRepository { + return NotificationRepositoryImp(dataManager) + } } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/NotificationRepository.kt b/app/src/main/java/org/mifos/mobile/repositories/NotificationRepository.kt new file mode 100644 index 000000000..19d4c2655 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/repositories/NotificationRepository.kt @@ -0,0 +1,9 @@ +package org.mifos.mobile.repositories + +import io.reactivex.Observable +import org.mifos.mobile.models.notification.MifosNotification + +interface NotificationRepository { + + fun loadNotifications(): Observable?>? +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/NotificationRepositoryImp.kt b/app/src/main/java/org/mifos/mobile/repositories/NotificationRepositoryImp.kt new file mode 100644 index 000000000..fa4ed2ace --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/repositories/NotificationRepositoryImp.kt @@ -0,0 +1,12 @@ +package org.mifos.mobile.repositories + +import io.reactivex.Observable +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.notification.MifosNotification + +class NotificationRepositoryImp(private val dataManager: DataManager?) : NotificationRepository { + + override fun loadNotifications(): Observable?>? { + return dataManager?.notifications + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt index 8eb737f4b..817d11956 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/NotificationFragment.kt @@ -15,13 +15,11 @@ import org.mifos.mobile.utils.NotificationUiState import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentNotificationBinding import org.mifos.mobile.models.notification.MifosNotification -import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.adapters.NotificationAdapter import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.utils.DividerItemDecoration import org.mifos.mobile.utils.Network import org.mifos.mobile.viewModels.NotificationViewModel -import org.mifos.mobile.viewModels.NotificationViewModelFactory import javax.inject.Inject /** @@ -33,9 +31,6 @@ class NotificationFragment : BaseFragment(), OnRefreshListener { private val binding get() = _binding!! private lateinit var viewModel : NotificationViewModel - @Inject - lateinit var viewModelFactory : NotificationViewModelFactory - @JvmField @Inject var adapter: NotificationAdapter? = null @@ -52,7 +47,7 @@ class NotificationFragment : BaseFragment(), OnRefreshListener { ): View { _binding = FragmentNotificationBinding.inflate(inflater, container, false) val rootView = binding.root - viewModel = ViewModelProvider(this, viewModelFactory)[NotificationViewModel::class.java] + viewModel = ViewModelProvider(this)[NotificationViewModel::class.java] sweetUIErrorHandler = SweetUIErrorHandler(activity, rootView) val layoutManager = LinearLayoutManager(activity) layoutManager.orientation = LinearLayoutManager.VERTICAL diff --git a/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt index 03ee49473..857cd9af4 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt @@ -3,26 +3,28 @@ package org.mifos.mobile.viewModels import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers -import org.mifos.mobile.NotificationRepository +import org.mifos.mobile.repositories.NotificationRepositoryImp import org.mifos.mobile.utils.NotificationUiState import org.mifos.mobile.api.DataManager import org.mifos.mobile.models.notification.MifosNotification +import org.mifos.mobile.repositories.NotificationRepository import javax.inject.Inject -class NotificationViewModel @Inject constructor(private val dataManager : DataManager?): ViewModel() { +@HiltViewModel +class NotificationViewModel @Inject constructor(private val notificationRepositoryImp: NotificationRepository): ViewModel() { private val compositeDisposables: CompositeDisposable = CompositeDisposable() - private val notificationRepository = NotificationRepository(dataManager) private val _notificationUiState = MutableLiveData() val notificationUiState : LiveData get() = _notificationUiState fun loadNotifications() { _notificationUiState.value = NotificationUiState.Loading - notificationRepository.loadNotifications() + notificationRepositoryImp.loadNotifications() ?.observeOn(AndroidSchedulers.mainThread()) ?.subscribeOn(Schedulers.io()) ?.subscribeWith(object : DisposableObserver?>() { diff --git a/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModelFactory.kt b/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModelFactory.kt deleted file mode 100644 index b8d65999a..000000000 --- a/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModelFactory.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.mifos.mobile.viewModels - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import org.mifos.mobile.api.DataManager -import org.mifos.mobile.injection.PerActivity -import javax.inject.Inject - -@PerActivity -class NotificationViewModelFactory @Inject constructor(private val dataManager : DataManager?) : - ViewModelProvider.Factory { - - override fun create(modelClass: Class): T { - if (modelClass.isAssignableFrom(NotificationViewModel::class.java)) { - return NotificationViewModel(dataManager) as T - } - throw IllegalArgumentException("Unknown ViewModel class: " + modelClass.name) - } -} From 27673517750094d95908ebf9e2dc7add62480d6d Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Tue, 4 Jul 2023 16:57:33 +0530 Subject: [PATCH 18/35] feat : notification fragment migration 1. added unit tests for notification viewModel and repository --- .../repositories/NotificationRepository.kt | 2 +- .../repositories/NotificationRepositoryImp.kt | 7 +- .../viewModels/NotificationViewModel.kt | 4 +- .../NotificationRepositoryImpTest.kt | 60 ++++++++++++++ .../viewModels/NotificationViewModelTest.kt | 80 +++++++++++++++++++ 5 files changed, 146 insertions(+), 7 deletions(-) create mode 100644 app/src/test/java/org/mifos/mobile/repositories/NotificationRepositoryImpTest.kt create mode 100644 app/src/test/java/org/mifos/mobile/viewModels/NotificationViewModelTest.kt diff --git a/app/src/main/java/org/mifos/mobile/repositories/NotificationRepository.kt b/app/src/main/java/org/mifos/mobile/repositories/NotificationRepository.kt index 19d4c2655..96a4c4f2c 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/NotificationRepository.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/NotificationRepository.kt @@ -5,5 +5,5 @@ import org.mifos.mobile.models.notification.MifosNotification interface NotificationRepository { - fun loadNotifications(): Observable?>? + fun loadNotifications(): Observable?> } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/NotificationRepositoryImp.kt b/app/src/main/java/org/mifos/mobile/repositories/NotificationRepositoryImp.kt index fa4ed2ace..856f69970 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/NotificationRepositoryImp.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/NotificationRepositoryImp.kt @@ -3,10 +3,11 @@ package org.mifos.mobile.repositories import io.reactivex.Observable import org.mifos.mobile.api.DataManager import org.mifos.mobile.models.notification.MifosNotification +import javax.inject.Inject -class NotificationRepositoryImp(private val dataManager: DataManager?) : NotificationRepository { +class NotificationRepositoryImp @Inject constructor(private val dataManager: DataManager) : NotificationRepository { - override fun loadNotifications(): Observable?>? { - return dataManager?.notifications + override fun loadNotifications(): Observable?> { + return dataManager.notifications } } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt index 857cd9af4..365fe0a5b 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/NotificationViewModel.kt @@ -8,9 +8,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers -import org.mifos.mobile.repositories.NotificationRepositoryImp import org.mifos.mobile.utils.NotificationUiState -import org.mifos.mobile.api.DataManager import org.mifos.mobile.models.notification.MifosNotification import org.mifos.mobile.repositories.NotificationRepository import javax.inject.Inject @@ -25,7 +23,7 @@ class NotificationViewModel @Inject constructor(private val notificationReposito fun loadNotifications() { _notificationUiState.value = NotificationUiState.Loading notificationRepositoryImp.loadNotifications() - ?.observeOn(AndroidSchedulers.mainThread()) + .observeOn(AndroidSchedulers.mainThread()) ?.subscribeOn(Schedulers.io()) ?.subscribeWith(object : DisposableObserver?>() { override fun onComplete() {} diff --git a/app/src/test/java/org/mifos/mobile/repositories/NotificationRepositoryImpTest.kt b/app/src/test/java/org/mifos/mobile/repositories/NotificationRepositoryImpTest.kt new file mode 100644 index 000000000..7fd5615d7 --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/repositories/NotificationRepositoryImpTest.kt @@ -0,0 +1,60 @@ +package org.mifos.mobile.repositories + +import io.reactivex.Observable + +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.notification.MifosNotification +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner + +@RunWith(MockitoJUnitRunner::class) +class NotificationRepositoryImpTest { + + @Mock + lateinit var dataManager: DataManager + + private lateinit var notificationRepositoryImp: NotificationRepository + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + notificationRepositoryImp = NotificationRepositoryImp(dataManager) + } + + @Test + fun testLoadNotifications_SuccessResponseReceivedFromDataManager_ReturnsSuccess() { + val notificationList : List = ArrayList() + val successResponse: Observable?> = + Observable.just(notificationList) + Mockito.`when`( + dataManager.notifications + ).thenReturn(successResponse) + + val result = notificationRepositoryImp.loadNotifications() + + Mockito.verify(dataManager).notifications + Assert.assertEquals(result, successResponse) + + } + + @Test + fun testLoadNotifications_ErrorResponseReceivedFromDataManager_ReturnsError() { + val errorResponse: Observable?> = + Observable.error(Throwable("LoadNotifications Unsuccessful")) + Mockito.`when`( + dataManager.notifications + ).thenReturn(errorResponse) + + val result = notificationRepositoryImp.loadNotifications() + + Mockito.verify(dataManager).notifications + Assert.assertEquals(result, errorResponse) + } + +} \ No newline at end of file diff --git a/app/src/test/java/org/mifos/mobile/viewModels/NotificationViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/NotificationViewModelTest.kt new file mode 100644 index 000000000..c10fb80c9 --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/viewModels/NotificationViewModelTest.kt @@ -0,0 +1,80 @@ +package org.mifos.mobile.viewModels + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import androidx.lifecycle.Observer +import io.reactivex.Observable +import org.junit.After +import org.junit.Assert.* +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mifos.mobile.models.notification.MifosNotification +import org.mifos.mobile.repositories.NotificationRepository +import org.mifos.mobile.util.RxSchedulersOverrideRule +import org.mifos.mobile.utils.NotificationUiState +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner +import java.lang.RuntimeException + +@RunWith(MockitoJUnitRunner::class) +class NotificationViewModelTest { + + @JvmField + @Rule + val mOverrideSchedulersRule = RxSchedulersOverrideRule() + + @get:Rule + val rule = InstantTaskExecutorRule() + + @Mock + lateinit var notificationRepositoryImp: NotificationRepository + + @Mock + lateinit var notificationUiStateObserver: Observer + + private lateinit var notificationViewModel: NotificationViewModel + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + notificationViewModel = NotificationViewModel(notificationRepositoryImp) + notificationViewModel.notificationUiState.observeForever(notificationUiStateObserver) + } + + @Test + fun testLoadNotifications_NotificationsSuccessfullyReceivedFromRepository_ReturnsNotificationsSuccessfully() { + val notificationsReceived: List = ArrayList() + Mockito.`when`( + notificationRepositoryImp.loadNotifications() + ).thenReturn(Observable.just(notificationsReceived)) + + notificationViewModel.loadNotifications() + + Mockito.verify(notificationUiStateObserver).onChanged(NotificationUiState.Loading) + Mockito.verify(notificationUiStateObserver).onChanged(NotificationUiState.LoadNotificationsSuccessful(notificationsReceived)) + Mockito.verifyNoMoreInteractions(notificationUiStateObserver) + } + + @Test + fun testLoadNotifications_NotificationsNotReceivedFromRepository_ReturnsError() { + val error = RuntimeException("loadNotifications Unsuccessful") + Mockito.`when`( + notificationRepositoryImp.loadNotifications() + ).thenReturn(Observable.error(error)) + + notificationViewModel.loadNotifications() + + Mockito.verify(notificationUiStateObserver).onChanged(NotificationUiState.Loading) + Mockito.verify(notificationUiStateObserver).onChanged(NotificationUiState.Error) + Mockito.verifyNoMoreInteractions(notificationUiStateObserver) + + } + + @After + fun tearDown() { + notificationViewModel.notificationUiState.removeObserver(notificationUiStateObserver) + } +} \ No newline at end of file From 57270b912a11c9972006357b3fc82e2c7d65d35e Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Tue, 4 Jul 2023 23:08:23 +0530 Subject: [PATCH 19/35] fix : RegistrationVerificationFragment migration to MVVM 1. deleted registerationVerification viewModel and moved logic to registration viewModel. 2. added unit tests for registerationVerification's verifyUser function of viewModel and repository. 3. moved UI state change logic to registerationVerificationUiState sealed class. --- .../mobile/repositories/UserAuthRepository.kt | 3 ++ .../repositories/UserAuthRepositoryImp.kt | 5 ++ .../RegistrationVerificationFragment.kt | 32 +++++++------ .../utils/RegistrationVerificationUiState.kt | 8 ++++ .../RegistrationVerificationViewModel.kt | 46 ------------------- ...egistrationVerificationViewModelFactory.kt | 17 ------- .../viewModels/RegistrationViewModel.kt | 24 ++++++++++ .../repositories/UserAuthRepositoryImpTest.kt | 31 ++++++++++++- .../viewModels/RegistrationViewModelTest.kt | 46 ++++++++++++++++++- 9 files changed, 131 insertions(+), 81 deletions(-) create mode 100644 app/src/main/java/org/mifos/mobile/utils/RegistrationVerificationUiState.kt delete mode 100644 app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModel.kt delete mode 100644 app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModelFactory.kt diff --git a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt index 145c251ef..e8f159d79 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt @@ -2,6 +2,7 @@ package org.mifos.mobile.repositories import io.reactivex.Observable import okhttp3.ResponseBody +import org.mifos.mobile.models.register.UserVerify interface UserAuthRepository { @@ -15,4 +16,6 @@ interface UserAuthRepository { password: String?, username: String? ): Observable? + + fun verifyUser(userVerify: UserVerify?): Observable? } diff --git a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt index 27f45872d..e28f6c1a3 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt @@ -4,6 +4,7 @@ import io.reactivex.Observable import okhttp3.ResponseBody import org.mifos.mobile.api.DataManager import org.mifos.mobile.models.register.RegisterPayload +import org.mifos.mobile.models.register.UserVerify import javax.inject.Inject class UserAuthRepositoryImp @Inject constructor(private val dataManager: DataManager) : @@ -31,4 +32,8 @@ class UserAuthRepositoryImp @Inject constructor(private val dataManager: DataMan } return dataManager.registerUser(registerPayload) } + + override fun verifyUser(userVerify: UserVerify?): Observable? { + return dataManager.verifyUser(userVerify) + } } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt index 137d3f162..e0e778bb6 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt @@ -14,10 +14,9 @@ import org.mifos.mobile.models.register.UserVerify import org.mifos.mobile.ui.activities.LoginActivity import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.utils.MFErrorParser +import org.mifos.mobile.utils.RegistrationVerificationUiState import org.mifos.mobile.utils.Toaster -import org.mifos.mobile.viewModels.RegistrationVerificationViewModel -import org.mifos.mobile.viewModels.RegistrationVerificationViewModelFactory -import javax.inject.Inject +import org.mifos.mobile.viewModels.RegistrationViewModel /** * Created by dilpreet on 31/7/17. @@ -26,10 +25,7 @@ import javax.inject.Inject class RegistrationVerificationFragment : BaseFragment() { private var _binding: FragmentRegistrationVerificationBinding? = null private val binding get() = _binding!! - private lateinit var viewModel : RegistrationVerificationViewModel - - @Inject - lateinit var viewModelFactory : RegistrationVerificationViewModelFactory + private lateinit var viewModel: RegistrationViewModel override fun onCreateView( inflater: LayoutInflater, @@ -38,20 +34,26 @@ class RegistrationVerificationFragment : BaseFragment() { ): View { _binding = FragmentRegistrationVerificationBinding.inflate(inflater, container, false) val rootView = binding.root - (activity as BaseActivity?)?.activityComponent?.inject(this) - viewModel = ViewModelProvider(this, viewModelFactory)[RegistrationVerificationViewModel::class.java] + viewModel = ViewModelProvider(this)[RegistrationViewModel::class.java] return rootView } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - viewModel.readVerificationResultSuccess.observe(viewLifecycleOwner) { verificationResultSuccess -> - hideProgress() - if (verificationResultSuccess == true) { - showVerifiedSuccessfully() - } else { - showError(MFErrorParser.errorMessage(viewModel.readExceptionOnVerification)) + viewModel.registrationVerificationUiState.observe(viewLifecycleOwner) { state -> + when (state) { + RegistrationVerificationUiState.Loading -> showProgress() + + RegistrationVerificationUiState.RegistrationVerificationSuccessful -> { + hideProgress() + showVerifiedSuccessfully() + } + + is RegistrationVerificationUiState.ErrorOnRegistrationVerification -> { + hideProgress() + showError(MFErrorParser.errorMessage(state.exception)) + } } } diff --git a/app/src/main/java/org/mifos/mobile/utils/RegistrationVerificationUiState.kt b/app/src/main/java/org/mifos/mobile/utils/RegistrationVerificationUiState.kt new file mode 100644 index 000000000..25506244b --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/utils/RegistrationVerificationUiState.kt @@ -0,0 +1,8 @@ +package org.mifos.mobile.utils + +sealed class RegistrationVerificationUiState { + object Loading : RegistrationVerificationUiState() + object RegistrationVerificationSuccessful : RegistrationVerificationUiState() + data class ErrorOnRegistrationVerification(val exception: Throwable) : + RegistrationVerificationUiState() +} diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModel.kt deleted file mode 100644 index e21af41b3..000000000 --- a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModel.kt +++ /dev/null @@ -1,46 +0,0 @@ -package org.mifos.mobile.viewModels - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.disposables.CompositeDisposable -import io.reactivex.observers.DisposableObserver -import io.reactivex.schedulers.Schedulers -import okhttp3.ResponseBody -import org.mifos.mobile.api.DataManager -import org.mifos.mobile.models.register.UserVerify -import javax.inject.Inject - -class RegistrationVerificationViewModel @Inject constructor(private val dataManager : DataManager?) : ViewModel() { - - private val compositeDisposables : CompositeDisposable = CompositeDisposable() - - private var verificationResultSuccess = MutableLiveData() - val readVerificationResultSuccess : LiveData get() = verificationResultSuccess - - private var exceptionOnVerification : Throwable? = null - val readExceptionOnVerification : Throwable? get() = exceptionOnVerification!! - - fun verifyUser(userVerify: UserVerify?) { - dataManager?.verifyUser(userVerify) - ?.observeOn(AndroidSchedulers.mainThread()) - ?.subscribeOn(Schedulers.io()) - ?.subscribeWith(object : DisposableObserver() { - override fun onComplete() {} - override fun onError(e: Throwable) { - exceptionOnVerification = e - verificationResultSuccess.value = false - } - - override fun onNext(responseBody: ResponseBody) { - verificationResultSuccess.value = true - } - })?.let { compositeDisposables.add(it) } - } - - override fun onCleared() { - super.onCleared() - compositeDisposables.clear() - } -} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModelFactory.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModelFactory.kt deleted file mode 100644 index 0d0fc5e79..000000000 --- a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationVerificationViewModelFactory.kt +++ /dev/null @@ -1,17 +0,0 @@ -package org.mifos.mobile.viewModels - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import org.mifos.mobile.api.DataManager -import javax.inject.Inject - -class RegistrationVerificationViewModelFactory @Inject constructor(private val dataManager: DataManager?) - : ViewModelProvider.Factory { - - override fun create(modelClass: Class): T { - if (modelClass.isAssignableFrom(RegistrationVerificationViewModel::class.java)) { - return RegistrationVerificationViewModel(dataManager) as T - } - throw IllegalArgumentException("Unknown ViewModel class: " + modelClass.name) - } -} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt index f773d8d9f..39bfbd770 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt @@ -10,8 +10,10 @@ import io.reactivex.disposables.CompositeDisposable import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody +import org.mifos.mobile.models.register.UserVerify import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.utils.RegistrationUiState +import org.mifos.mobile.utils.RegistrationVerificationUiState import javax.inject.Inject @HiltViewModel @@ -22,6 +24,10 @@ class RegistrationViewModel @Inject constructor(private val userAuthRepositoryIm private val _registrationUiState = MutableLiveData() val registrationUiState: LiveData get() = _registrationUiState + private val _registrationVerificationUiState = + MutableLiveData() + val registrationVerificationUiState: LiveData get() = _registrationVerificationUiState + fun isInputFieldBlank(fieldText: String): Boolean { return fieldText.trim().isEmpty() } @@ -75,6 +81,24 @@ class RegistrationViewModel @Inject constructor(private val userAuthRepositoryIm })?.let { compositeDisposables.add(it) } } + fun verifyUser(userVerify: UserVerify?) { + _registrationVerificationUiState.value = RegistrationVerificationUiState.Loading + userAuthRepositoryImp.verifyUser(userVerify)?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribeOn(Schedulers.io()) + ?.subscribeWith(object : DisposableObserver() { + override fun onComplete() {} + override fun onError(e: Throwable) { + _registrationVerificationUiState.value = + RegistrationVerificationUiState.ErrorOnRegistrationVerification(e) + } + + override fun onNext(responseBody: ResponseBody) { + _registrationVerificationUiState.value = + RegistrationVerificationUiState.RegistrationVerificationSuccessful + } + })?.let { compositeDisposables.add(it) } + } + override fun onCleared() { super.onCleared() compositeDisposables.clear() diff --git a/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt b/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt index bd2b68744..a1cffde64 100644 --- a/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt +++ b/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt @@ -6,6 +6,7 @@ import org.junit.Assert import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.mifos.mobile.FakeRemoteDataSource.userVerify import org.mifos.mobile.api.DataManager import org.mifos.mobile.models.register.RegisterPayload import org.mockito.Mock @@ -19,7 +20,7 @@ class UserAuthRepositoryImpTest { @Mock lateinit var dataManager: DataManager - private lateinit var userAuthRepositoryImp: UserAuthRepositoryImp + private lateinit var userAuthRepositoryImp: UserAuthRepository @Before fun setUp() { @@ -89,4 +90,32 @@ class UserAuthRepositoryImpTest { Mockito.verify(dataManager).registerUser(registerPayload) Assert.assertEquals(result, error) } + + @Test + fun testVerifyUser_SuccessResponseReceivedFromDataManager_ReturnsSuccessfulRegistrationVerification() { + val successResponse: Observable = + Observable.just(Mockito.mock(ResponseBody::class.java)) + Mockito.`when`( + dataManager.verifyUser(userVerify) + ).thenReturn(successResponse) + + val result = userAuthRepositoryImp.verifyUser(userVerify) + + Mockito.verify(dataManager).verifyUser(userVerify) + Assert.assertEquals(result, successResponse) + } + + @Test + fun testVerifyUser_ErrorResponseReceivedFromDataManager_ReturnsUnsuccessfulRegistrationVerification() { + val errorResponse: Observable = + Observable.error(Throwable("RegistrationVerification failed")) + Mockito.`when`( + dataManager.verifyUser(userVerify) + ).thenReturn(errorResponse) + + val result = userAuthRepositoryImp.verifyUser(userVerify) + Mockito.verify(dataManager).verifyUser(userVerify) + Assert.assertEquals(result, errorResponse) + + } } \ No newline at end of file diff --git a/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt index 63d0f6d64..f882cd7d7 100644 --- a/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt +++ b/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt @@ -10,9 +10,11 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mifos.mobile.repositories.UserAuthRepositoryImp +import org.mifos.mobile.FakeRemoteDataSource.userVerify +import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.util.RxSchedulersOverrideRule import org.mifos.mobile.utils.RegistrationUiState +import org.mifos.mobile.utils.RegistrationVerificationUiState import org.mockito.Mock import org.mockito.Mockito import org.mockito.MockitoAnnotations @@ -30,11 +32,14 @@ class RegistrationViewModelTest { val rule = InstantTaskExecutorRule() @Mock - lateinit var userAuthRepositoryImp: UserAuthRepositoryImp + lateinit var userAuthRepositoryImp: UserAuthRepository @Mock lateinit var registrationUiStateObserver: Observer + @Mock + lateinit var registrationVerificationUiStateObserver: Observer + private lateinit var registrationViewModel: RegistrationViewModel @Before @@ -42,6 +47,9 @@ class RegistrationViewModelTest { MockitoAnnotations.openMocks(this) registrationViewModel = RegistrationViewModel(userAuthRepositoryImp) registrationViewModel.registrationUiState.observeForever(registrationUiStateObserver) + registrationViewModel.registrationVerificationUiState.observeForever( + registrationVerificationUiStateObserver + ) } @Test @@ -166,8 +174,42 @@ class RegistrationViewModelTest { Mockito.verifyNoMoreInteractions(registrationUiStateObserver) } + @Test + fun testVerifyUser_SuccessfulRegistrationVerificationReceivedFromRepository_ReturnsRegistrationVerificationSuccessful() { + Mockito.`when`( + userAuthRepositoryImp.verifyUser(userVerify) + ).thenReturn(Observable.just(Mockito.mock(ResponseBody::class.java))) + + registrationViewModel.verifyUser(userVerify) + + Mockito.verify(registrationVerificationUiStateObserver) + .onChanged(RegistrationVerificationUiState.Loading) + Mockito.verify(registrationVerificationUiStateObserver) + .onChanged(RegistrationVerificationUiState.RegistrationVerificationSuccessful) + Mockito.verifyNoMoreInteractions(registrationUiStateObserver) + } + + @Test + fun testVerifyUser_UnsuccessfulRegistrationVerificationReceivedFromRepository_ReturnsRegistrationVerificationUnsuccessful() { + val error = RuntimeException("RegistrationVerification Failed") + Mockito.`when`( + userAuthRepositoryImp.verifyUser(userVerify) + ).thenReturn(Observable.error(error)) + + registrationViewModel.verifyUser(userVerify) + + Mockito.verify(registrationVerificationUiStateObserver) + .onChanged(RegistrationVerificationUiState.Loading) + Mockito.verify(registrationVerificationUiStateObserver) + .onChanged(RegistrationVerificationUiState.ErrorOnRegistrationVerification(error)) + Mockito.verifyNoMoreInteractions(registrationUiStateObserver) + } + @After fun tearDown() { registrationViewModel.registrationUiState.removeObserver(registrationUiStateObserver) + registrationViewModel.registrationVerificationUiState.removeObserver( + registrationVerificationUiStateObserver + ) } } \ No newline at end of file From a648a6204e3ab7b0994cfbe074404404791aea0f Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Tue, 4 Jul 2023 23:59:19 +0530 Subject: [PATCH 20/35] fix : registration verification fragment mvvm migration shifted userVerify payload creation to datalayer(i.e. in repository) --- .../org/mifos/mobile/repositories/UserAuthRepository.kt | 3 +-- .../mifos/mobile/repositories/UserAuthRepositoryImp.kt | 6 +++++- .../ui/fragments/RegistrationVerificationFragment.kt | 9 +++------ .../org/mifos/mobile/viewModels/RegistrationViewModel.kt | 5 ++--- .../mobile/repositories/UserAuthRepositoryImpTest.kt | 6 ++++-- .../mifos/mobile/viewModels/RegistrationViewModelTest.kt | 9 ++++----- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt index e8f159d79..d42f678ea 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt @@ -2,7 +2,6 @@ package org.mifos.mobile.repositories import io.reactivex.Observable import okhttp3.ResponseBody -import org.mifos.mobile.models.register.UserVerify interface UserAuthRepository { @@ -17,5 +16,5 @@ interface UserAuthRepository { username: String? ): Observable? - fun verifyUser(userVerify: UserVerify?): Observable? + fun verifyUser(authenticationToken: String?, requestId: String?): Observable? } diff --git a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt index e28f6c1a3..523dc55d0 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt @@ -33,7 +33,11 @@ class UserAuthRepositoryImp @Inject constructor(private val dataManager: DataMan return dataManager.registerUser(registerPayload) } - override fun verifyUser(userVerify: UserVerify?): Observable? { + override fun verifyUser(authenticationToken: String?, requestId: String?): Observable? { + val userVerify = UserVerify().apply { + this.authenticationToken = authenticationToken + this.requestId = requestId + } return dataManager.verifyUser(userVerify) } } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt index e0e778bb6..c45b2dbe2 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt @@ -10,7 +10,6 @@ import androidx.lifecycle.ViewModelProvider import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentRegistrationVerificationBinding -import org.mifos.mobile.models.register.UserVerify import org.mifos.mobile.ui.activities.LoginActivity import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.utils.MFErrorParser @@ -63,11 +62,9 @@ class RegistrationVerificationFragment : BaseFragment() { } private fun verifyClicked() { - val userVerify = UserVerify() - userVerify.authenticationToken = binding.etAuthenticationToken.text.toString() - userVerify.requestId = binding.etRequestId.text.toString() - showProgress() - viewModel.verifyUser(userVerify) + val authenticationToken = binding.etAuthenticationToken.text.toString() + val requestId = binding.etRequestId.text.toString() + viewModel.verifyUser(authenticationToken, requestId) } private fun showVerifiedSuccessfully() { diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt index 39bfbd770..7b9b2b31e 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt @@ -10,7 +10,6 @@ import io.reactivex.disposables.CompositeDisposable import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody -import org.mifos.mobile.models.register.UserVerify import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.utils.RegistrationUiState import org.mifos.mobile.utils.RegistrationVerificationUiState @@ -81,9 +80,9 @@ class RegistrationViewModel @Inject constructor(private val userAuthRepositoryIm })?.let { compositeDisposables.add(it) } } - fun verifyUser(userVerify: UserVerify?) { + fun verifyUser(authenticationToken: String?, requestId: String?) { _registrationVerificationUiState.value = RegistrationVerificationUiState.Loading - userAuthRepositoryImp.verifyUser(userVerify)?.observeOn(AndroidSchedulers.mainThread()) + userAuthRepositoryImp.verifyUser(authenticationToken, requestId)?.observeOn(AndroidSchedulers.mainThread()) ?.subscribeOn(Schedulers.io()) ?.subscribeWith(object : DisposableObserver() { override fun onComplete() {} diff --git a/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt b/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt index a1cffde64..50bf0897f 100644 --- a/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt +++ b/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt @@ -99,7 +99,8 @@ class UserAuthRepositoryImpTest { dataManager.verifyUser(userVerify) ).thenReturn(successResponse) - val result = userAuthRepositoryImp.verifyUser(userVerify) + val result = + userAuthRepositoryImp.verifyUser(userVerify.authenticationToken, userVerify.requestId) Mockito.verify(dataManager).verifyUser(userVerify) Assert.assertEquals(result, successResponse) @@ -113,7 +114,8 @@ class UserAuthRepositoryImpTest { dataManager.verifyUser(userVerify) ).thenReturn(errorResponse) - val result = userAuthRepositoryImp.verifyUser(userVerify) + val result = + userAuthRepositoryImp.verifyUser(userVerify.authenticationToken, userVerify.requestId) Mockito.verify(dataManager).verifyUser(userVerify) Assert.assertEquals(result, errorResponse) diff --git a/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt index f882cd7d7..a13b34559 100644 --- a/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt +++ b/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt @@ -10,7 +10,6 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mifos.mobile.FakeRemoteDataSource.userVerify import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.util.RxSchedulersOverrideRule import org.mifos.mobile.utils.RegistrationUiState @@ -177,10 +176,10 @@ class RegistrationViewModelTest { @Test fun testVerifyUser_SuccessfulRegistrationVerificationReceivedFromRepository_ReturnsRegistrationVerificationSuccessful() { Mockito.`when`( - userAuthRepositoryImp.verifyUser(userVerify) + userAuthRepositoryImp.verifyUser(Mockito.anyString(), Mockito.anyString()) ).thenReturn(Observable.just(Mockito.mock(ResponseBody::class.java))) - registrationViewModel.verifyUser(userVerify) + registrationViewModel.verifyUser("authenticationToken", "requestId") Mockito.verify(registrationVerificationUiStateObserver) .onChanged(RegistrationVerificationUiState.Loading) @@ -193,10 +192,10 @@ class RegistrationViewModelTest { fun testVerifyUser_UnsuccessfulRegistrationVerificationReceivedFromRepository_ReturnsRegistrationVerificationUnsuccessful() { val error = RuntimeException("RegistrationVerification Failed") Mockito.`when`( - userAuthRepositoryImp.verifyUser(userVerify) + userAuthRepositoryImp.verifyUser(Mockito.anyString(), Mockito.anyString()) ).thenReturn(Observable.error(error)) - registrationViewModel.verifyUser(userVerify) + registrationViewModel.verifyUser("authenticationToken", "requestId") Mockito.verify(registrationVerificationUiStateObserver) .onChanged(RegistrationVerificationUiState.Loading) From b0b93689cd238d2bc101b54995c7e7d46014fbdc Mon Sep 17 00:00:00 2001 From: Pratyush Singh Date: Fri, 7 Jul 2023 01:38:30 +0530 Subject: [PATCH 21/35] feat: recent transaction fragment to mvvm --- .../injection/module/RepositoryModule.kt | 7 ++ .../RecentTransactionRepository.kt | 14 ++++ .../RecentTransactionRepositoryImp.kt | 15 ++++ .../fragments/RecentTransactionsFragment.kt | 72 ++++++++++++------- .../mobile/utils/RecentTransactionUiState.kt | 11 +++ .../viewModels/RecentTransactionViewModel.kt | 68 ++++++++++++++++++ 6 files changed, 160 insertions(+), 27 deletions(-) create mode 100644 app/src/main/java/org/mifos/mobile/repositories/RecentTransactionRepository.kt create mode 100644 app/src/main/java/org/mifos/mobile/repositories/RecentTransactionRepositoryImp.kt create mode 100644 app/src/main/java/org/mifos/mobile/utils/RecentTransactionUiState.kt create mode 100644 app/src/main/java/org/mifos/mobile/viewModels/RecentTransactionViewModel.kt diff --git a/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt index 2063047cc..89d331320 100644 --- a/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt +++ b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt @@ -5,6 +5,8 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import org.mifos.mobile.api.DataManager +import org.mifos.mobile.repositories.RecentTransactionRepository +import org.mifos.mobile.repositories.RecentTransactionRepositoryImp import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.repositories.UserAuthRepositoryImp @@ -16,4 +18,9 @@ class RepositoryModule { fun providesUserAuthRepository(dataManager: DataManager): UserAuthRepository { return UserAuthRepositoryImp(dataManager) } + + @Provides + fun providesRecentTransactionRepository(dataManager: DataManager): RecentTransactionRepository { + return RecentTransactionRepositoryImp(dataManager) + } } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/RecentTransactionRepository.kt b/app/src/main/java/org/mifos/mobile/repositories/RecentTransactionRepository.kt new file mode 100644 index 000000000..ea184ec98 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/repositories/RecentTransactionRepository.kt @@ -0,0 +1,14 @@ +package org.mifos.mobile.repositories + + +import io.reactivex.Observable +import org.mifos.mobile.models.Page +import org.mifos.mobile.models.Transaction + +interface RecentTransactionRepository { + + fun recentTransactions( + offset: Int?, + limit: Int? + ): Observable?>? +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/RecentTransactionRepositoryImp.kt b/app/src/main/java/org/mifos/mobile/repositories/RecentTransactionRepositoryImp.kt new file mode 100644 index 000000000..da822044a --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/repositories/RecentTransactionRepositoryImp.kt @@ -0,0 +1,15 @@ +package org.mifos.mobile.repositories + +import io.reactivex.Observable +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.Page +import org.mifos.mobile.models.Transaction +import javax.inject.Inject + +class RecentTransactionRepositoryImp @Inject constructor(private val dataManager: DataManager) : + RecentTransactionRepository { + + override fun recentTransactions(offset: Int?, limit: Int?): Observable?>? { + return limit?.let { offset?.let { it1 -> dataManager.getRecentTransactions(it1, it) } } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt index 33fb7d214..fa64eacc9 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RecentTransactionsFragment.kt @@ -6,6 +6,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast +import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener @@ -14,16 +15,12 @@ import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentRecentTransactionsBinding import org.mifos.mobile.models.Transaction -import org.mifos.mobile.presenters.RecentTransactionsPresenter import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.adapters.RecentTransactionListAdapter import org.mifos.mobile.ui.fragments.base.BaseFragment -import org.mifos.mobile.ui.views.RecentTransactionsView -import org.mifos.mobile.utils.Constants -import org.mifos.mobile.utils.DividerItemDecoration -import org.mifos.mobile.utils.EndlessRecyclerViewScrollListener +import org.mifos.mobile.utils.* import org.mifos.mobile.utils.Network.isConnected -import org.mifos.mobile.utils.Toaster +import org.mifos.mobile.viewModels.RecentTransactionViewModel import javax.inject.Inject /** @@ -31,18 +28,17 @@ import javax.inject.Inject * @since 09/08/16 */ @AndroidEntryPoint -class RecentTransactionsFragment : BaseFragment(), RecentTransactionsView, OnRefreshListener { +class RecentTransactionsFragment : BaseFragment(), OnRefreshListener { private var _binding: FragmentRecentTransactionsBinding? = null private val binding get() = _binding!! - @JvmField - @Inject - var recentTransactionsPresenter: RecentTransactionsPresenter? = null - @JvmField @Inject var recentTransactionsListAdapter: RecentTransactionListAdapter? = null + + private lateinit var recentTransactionViewModel: RecentTransactionViewModel + private var sweetUIErrorHandler: SweetUIErrorHandler? = null private var recentTransactionList: MutableList? = null override fun onCreate(savedInstanceState: Bundle?) { @@ -56,18 +52,41 @@ class RecentTransactionsFragment : BaseFragment(), RecentTransactionsView, OnRef savedInstanceState: Bundle?, ): View { _binding = FragmentRecentTransactionsBinding.inflate(inflater, container, false) - recentTransactionsPresenter?.attachView(this) + recentTransactionViewModel = ViewModelProvider(this)[RecentTransactionViewModel::class.java] sweetUIErrorHandler = SweetUIErrorHandler(activity, binding.root) showUserInterface() setToolbarTitle(getString(R.string.recent_transactions)) if (savedInstanceState == null) { - recentTransactionsPresenter?.loadRecentTransactions(false, 0) + recentTransactionViewModel.loadRecentTransactions(false, 0) } return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + recentTransactionViewModel.recentTransactionUiState.observe(viewLifecycleOwner) { + when (it) { + is RecentTransactionUiState.Loading -> showProgress() + is RecentTransactionUiState.RecentTransactions -> { + hideProgress() + showRecentTransactions(it.transactions) + } + is RecentTransactionUiState.Error -> { + hideProgress() + showMessage(getString(it.message)) + } + is RecentTransactionUiState.EmptyTransaction -> { + hideProgress() + showEmptyTransaction() + } + is RecentTransactionUiState.LoadMoreRecentTransactions -> { + hideProgress() + showLoadMoreRecentTransactions(it.transactions) + } + } + } + binding.layoutError.btnTryAgain.setOnClickListener { retryClicked() } @@ -95,7 +114,7 @@ class RecentTransactionsFragment : BaseFragment(), RecentTransactionsView, OnRef /** * Setting up `rvRecentTransactions` */ - override fun showUserInterface() { + fun showUserInterface() { val layoutManager = LinearLayoutManager(activity) layoutManager.orientation = LinearLayoutManager.VERTICAL binding.rvRecentTransactions.layoutManager = layoutManager @@ -111,7 +130,7 @@ class RecentTransactionsFragment : BaseFragment(), RecentTransactionsView, OnRef binding.rvRecentTransactions.addOnScrollListener( object : EndlessRecyclerViewScrollListener(layoutManager) { override fun onLoadMore(page: Int, totalItemsCount: Int, view: RecyclerView?) { - recentTransactionsPresenter?.loadRecentTransactions(true, totalItemsCount) + recentTransactionViewModel.loadRecentTransactions(true, totalItemsCount) } override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { @@ -138,13 +157,13 @@ class RecentTransactionsFragment : BaseFragment(), RecentTransactionsView, OnRef if (binding.layoutError.root.visibility == View.VISIBLE) { resetUI() } - recentTransactionsPresenter?.loadRecentTransactions(false, 0) + recentTransactionViewModel.loadRecentTransactions(false, 0) } /** * Shows a Toast */ - override fun showMessage(message: String?) { + fun showMessage(message: String?) { (activity as BaseActivity?)?.showToast(message!!) } @@ -154,7 +173,7 @@ class RecentTransactionsFragment : BaseFragment(), RecentTransactionsView, OnRef * * @param recentTransactionList List of [Transaction] */ - override fun showRecentTransactions(recentTransactionList: List?) { + fun showRecentTransactions(recentTransactionList: List?) { this.recentTransactionList = recentTransactionList as MutableList? recentTransactionsListAdapter?.setTransactions(recentTransactionList) } @@ -164,12 +183,12 @@ class RecentTransactionsFragment : BaseFragment(), RecentTransactionsView, OnRef * * @param transactions List of [Transaction] */ - override fun showLoadMoreRecentTransactions(transactions: List?) { + fun showLoadMoreRecentTransactions(transactions: List?) { this.recentTransactionList?.addAll(recentTransactionList!!) recentTransactionsListAdapter?.notifyDataSetChanged() } - override fun resetUI() { + fun resetUI() { sweetUIErrorHandler?.hideSweetErrorLayoutUI( binding.rvRecentTransactions, binding.layoutError.root, @@ -179,7 +198,7 @@ class RecentTransactionsFragment : BaseFragment(), RecentTransactionsView, OnRef /** * Hides `rvRecentTransactions` and shows a textview prompting no transactions */ - override fun showEmptyTransaction() { + fun showEmptyTransaction() { sweetUIErrorHandler?.showSweetEmptyUI( getString(R.string.recent_transactions), R.drawable.ic_error_black_24dp, @@ -193,7 +212,7 @@ class RecentTransactionsFragment : BaseFragment(), RecentTransactionsView, OnRef * * @param message Error message that tells the user about the problem. */ - override fun showErrorFetchingRecentTransactions(message: String?) { + fun showErrorFetchingRecentTransactions(message: String?) { if (!isConnected(requireActivity())) { sweetUIErrorHandler?.showSweetNoInternetUI( binding.rvRecentTransactions, @@ -214,7 +233,7 @@ class RecentTransactionsFragment : BaseFragment(), RecentTransactionsView, OnRef binding.rvRecentTransactions, binding.layoutError.root, ) - recentTransactionsPresenter?.loadRecentTransactions(false, 0) + recentTransactionViewModel.loadRecentTransactions(false, 0) } else { Toast.makeText( context, @@ -224,15 +243,15 @@ class RecentTransactionsFragment : BaseFragment(), RecentTransactionsView, OnRef } } - override fun showProgress() { + fun showProgress() { showSwipeRefreshLayout(true) } - override fun hideProgress() { + fun hideProgress() { showSwipeRefreshLayout(false) } - override fun showSwipeRefreshLayout(show: Boolean) { + fun showSwipeRefreshLayout(show: Boolean) { binding.swipeTransactionContainer.post { binding.swipeTransactionContainer.isRefreshing = show } @@ -240,7 +259,6 @@ class RecentTransactionsFragment : BaseFragment(), RecentTransactionsView, OnRef override fun onDestroyView() { super.onDestroyView() - recentTransactionsPresenter?.detachView() _binding = null } diff --git a/app/src/main/java/org/mifos/mobile/utils/RecentTransactionUiState.kt b/app/src/main/java/org/mifos/mobile/utils/RecentTransactionUiState.kt new file mode 100644 index 000000000..2838e9512 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/utils/RecentTransactionUiState.kt @@ -0,0 +1,11 @@ +package org.mifos.mobile.utils + +import org.mifos.mobile.models.Transaction + +sealed class RecentTransactionUiState { + object Loading : RecentTransactionUiState() + object EmptyTransaction : RecentTransactionUiState() + data class Error(val message: Int) : RecentTransactionUiState() + data class RecentTransactions(val transactions: List) : RecentTransactionUiState() + data class LoadMoreRecentTransactions(val transactions: List) : RecentTransactionUiState() +} diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RecentTransactionViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/RecentTransactionViewModel.kt new file mode 100644 index 000000000..b4b2e1868 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/viewModels/RecentTransactionViewModel.kt @@ -0,0 +1,68 @@ +package org.mifos.mobile.viewModels + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.observers.DisposableObserver +import io.reactivex.schedulers.Schedulers +import org.mifos.mobile.R +import org.mifos.mobile.models.Page +import org.mifos.mobile.models.Transaction +import org.mifos.mobile.repositories.RecentTransactionRepository +import org.mifos.mobile.utils.RecentTransactionUiState +import javax.inject.Inject + +@HiltViewModel +class RecentTransactionViewModel @Inject constructor(private val recentTransactionRepositoryImp: RecentTransactionRepository) : + ViewModel() { + + private val compositeDisposables: CompositeDisposable = CompositeDisposable() + private val limit = 50 + private var loadmore = false + + private val _recentTransactionUiState = MutableLiveData() + val recentTransactionUiState: LiveData = _recentTransactionUiState + + fun loadRecentTransactions(loadmore: Boolean, offset: Int) { + this.loadmore = loadmore + loadRecentTransactions(offset, limit) + } + + private fun loadRecentTransactions(offset: Int, limit: Int) { + _recentTransactionUiState.value = RecentTransactionUiState.Loading + recentTransactionRepositoryImp.recentTransactions(offset, limit) + ?.observeOn( AndroidSchedulers.mainThread()) + ?.subscribeOn(Schedulers.io()) + ?.subscribeWith(object : DisposableObserver?>() { + override fun onNext(transactions: Page) { + if (transactions.totalFilteredRecords == 0) { + _recentTransactionUiState.value = RecentTransactionUiState.EmptyTransaction + } else if (loadmore && transactions.pageItems.isNotEmpty()) { + _recentTransactionUiState.value = RecentTransactionUiState.LoadMoreRecentTransactions(transactions.pageItems) + } else if (transactions.pageItems.isNotEmpty()) { + _recentTransactionUiState.value = RecentTransactionUiState.RecentTransactions(transactions.pageItems) + } + } + + override fun onError(e: Throwable) { + _recentTransactionUiState.value = RecentTransactionUiState.Error(R.string.recent_transactions) + } + + override fun onComplete() {} + }).let { + if (it != null) { + compositeDisposables.add( + it, + ) + } + } + } + + override fun onCleared() { + super.onCleared() + compositeDisposables.clear() + } +} \ No newline at end of file From 55fdbdc7d32017c45c326552cfb6e8a0eb63f16c Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Fri, 7 Jul 2023 11:27:17 +0530 Subject: [PATCH 22/35] feat : login activity mvvm migration --- .../mobile/repositories/UserAuthRepository.kt | 16 ++ .../repositories/UserAuthRepositoryImp.kt | 53 ++++++ .../mobile/ui/activities/LoginActivity.kt | 178 ++++++++++++++---- .../org/mifos/mobile/utils/LoginUiState.kt | 13 ++ .../mifos/mobile/viewModels/LoginViewModel.kt | 123 ++++++++++++ 5 files changed, 347 insertions(+), 36 deletions(-) create mode 100644 app/src/main/java/org/mifos/mobile/utils/LoginUiState.kt create mode 100644 app/src/main/java/org/mifos/mobile/viewModels/LoginViewModel.kt diff --git a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt index 145c251ef..05464116a 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt @@ -2,6 +2,9 @@ package org.mifos.mobile.repositories import io.reactivex.Observable import okhttp3.ResponseBody +import org.mifos.mobile.models.Page +import org.mifos.mobile.models.User +import org.mifos.mobile.models.client.Client interface UserAuthRepository { @@ -15,4 +18,17 @@ interface UserAuthRepository { password: String?, username: String? ): Observable? + + fun login(username: String, password: String): Observable? + + fun loadClient() : Observable?>? + + fun saveAuthenticationTokenForSession(user: User) + + fun reInitializeService() + + fun setClientId(clientId: Long?) + + fun clearPrefHelper() + } diff --git a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt index 27f45872d..e0d2fb6c3 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt @@ -2,13 +2,21 @@ package org.mifos.mobile.repositories import io.reactivex.Observable import okhttp3.ResponseBody +import org.mifos.mobile.api.BaseApiManager import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.Page +import org.mifos.mobile.models.User +import org.mifos.mobile.models.client.Client +import org.mifos.mobile.models.payload.LoginPayload import org.mifos.mobile.models.register.RegisterPayload +import org.mifos.mobile.utils.Constants import javax.inject.Inject class UserAuthRepositoryImp @Inject constructor(private val dataManager: DataManager) : UserAuthRepository { + private val preferencesHelper = dataManager.preferencesHelper + override fun registerUser( accountNumber: String?, authenticationMode: String?, @@ -31,4 +39,49 @@ class UserAuthRepositoryImp @Inject constructor(private val dataManager: DataMan } return dataManager.registerUser(registerPayload) } + + override fun login(username: String, password: String): Observable? { + val loginPayload = LoginPayload().apply { + this.username = username + this.password = password + } + return dataManager.login(loginPayload) + } + + override fun loadClient(): Observable?>? { + return dataManager.clients + } + + /** + * Save the authentication token from the server and the user ID. + * The authentication token would be used for accessing the authenticated + * APIs. + * + * @param userID - The userID of the user to be saved. + * @param authToken - The authentication token to be saved. + */ + override fun saveAuthenticationTokenForSession(user: User) { + val authToken = Constants.BASIC + user.base64EncodedAuthenticationKey + preferencesHelper.userName = user.username + preferencesHelper.userId = user.userId + preferencesHelper.saveToken(authToken) + reInitializeService() + } + + override fun reInitializeService() { + BaseApiManager.createService( + preferencesHelper.baseUrl, + preferencesHelper.tenant, + preferencesHelper.token, + ) + } + + override fun setClientId(clientId: Long?) { + preferencesHelper.clientId = clientId + dataManager.clientId = clientId + } + + override fun clearPrefHelper() { + preferencesHelper.clear() + } } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt b/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt index d76b27117..c7b863ea8 100644 --- a/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt +++ b/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt @@ -6,36 +6,34 @@ import android.view.View import android.view.ViewGroup import android.widget.EditText import android.widget.Toast +import androidx.lifecycle.ViewModelProvider import dagger.hilt.android.AndroidEntryPoint +import org.mifos.mobile.MifosSelfServiceApp.Companion.context import org.mifos.mobile.R import org.mifos.mobile.databinding.ActivityLoginBinding -import org.mifos.mobile.models.payload.LoginPayload -import org.mifos.mobile.presenters.LoginPresenter import org.mifos.mobile.ui.activities.base.BaseActivity -import org.mifos.mobile.ui.views.LoginView import org.mifos.mobile.utils.Constants +import org.mifos.mobile.utils.LoginUiState +import org.mifos.mobile.utils.MFErrorParser import org.mifos.mobile.utils.Network import org.mifos.mobile.utils.Toaster -import javax.inject.Inject +import org.mifos.mobile.viewModels.LoginViewModel /** * @author Vishwajeet * @since 05/06/16 */ @AndroidEntryPoint -class LoginActivity : BaseActivity(), LoginView { - - @JvmField - @Inject - var loginPresenter: LoginPresenter? = null +class LoginActivity : BaseActivity() { private lateinit var binding: ActivityLoginBinding + private lateinit var viewModel: LoginViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityLoginBinding.inflate(layoutInflater) setContentView(binding.root) - loginPresenter?.attachView(this) + viewModel = ViewModelProvider(this)[LoginViewModel::class.java] dismissSoftKeyboardOnBkgTap(binding.nsvBackground) binding.btnLogin.setOnClickListener { onLoginClicked() @@ -43,18 +41,63 @@ class LoginActivity : BaseActivity(), LoginView { binding.btnRegister.setOnClickListener { onRegisterClicked() } - binding.etUsername.setOnTouchListener { view, event -> + binding.etUsername.setOnTouchListener { view, _ -> onTouch(view) } - binding.etPassword.setOnTouchListener { view, event -> + binding.etPassword.setOnTouchListener { view, _ -> onTouch(view) } + + viewModel.loginUiState.observe(this) { state -> + when (state) { + LoginUiState.Loading -> showProgress() + + LoginUiState.DuringLoginError -> { + hideProgress() + showMessage(context?.getString(R.string.err_during_login)) + } + + LoginUiState.ServerDownError -> { + hideProgress() + showMessage(context?.getString(R.string.error_server_down)) + } + + LoginUiState.LoginSuccess -> { + onLoginSuccess() + } + + is LoginUiState.DynamicError -> { + hideProgress() + showMessage(MFErrorParser.parseError(state.errorMessage).developerMessage) + } + + LoginUiState.UnauthorisedClientError -> { + hideProgress() + showMessage(context?.getString(R.string.unauthorized_client)) + } + + LoginUiState.FetchingClientError -> { + hideProgress() + showMessage(context?.getString(R.string.error_fetching_client)) + } + + LoginUiState.ClientNotFoundError -> { + hideProgress() + showMessage(context?.getString(R.string.error_client_not_found)) + } + + is LoginUiState.LoadClientSuccess -> { + hideProgress() + showPassCodeActivity(state.clientName) + } + } + } } private fun dismissSoftKeyboardOnBkgTap(view: View) { if (view !is EditText) { - view.setOnTouchListener { view, event -> + view.setOnTouchListener { _, _ -> hideKeyboard(this@LoginActivity) false } @@ -67,10 +110,10 @@ class LoginActivity : BaseActivity(), LoginView { } } - fun onTouch(v: View): Boolean { + private fun onTouch(v: View): Boolean { when (v) { - binding.etUsername -> loginPresenter?.mvpView?.clearUsernameError() - binding.etPassword -> loginPresenter?.mvpView?.clearPasswordError() + binding.etUsername -> clearUsernameError() + binding.etPassword -> clearPasswordError() } return false } @@ -78,28 +121,28 @@ class LoginActivity : BaseActivity(), LoginView { /** * Called when Login is user has successfully logged in */ - override fun onLoginSuccess() { - loginPresenter?.loadClient() + private fun onLoginSuccess() { + viewModel.loadClient() } /** * Shows ProgressDialog when called */ - override fun showProgress() { + private fun showProgress() { showProgressDialog(getString(R.string.progress_message_login)) } /** * Hides the progressDialog which is being shown */ - override fun hideProgress() { + private fun hideProgress() { hideProgressDialog() } /** * Starts [PassCodeActivity] */ - override fun showPassCodeActivity(clientName: String?) { + private fun showPassCodeActivity(clientName: String?) { showToast(getString(R.string.toast_welcome, clientName)) startPassCodeActivity() } @@ -109,24 +152,24 @@ class LoginActivity : BaseActivity(), LoginView { * * @param errorMessage Error message that tells the user about the problem. */ - override fun showMessage(errorMessage: String?) { + private fun showMessage(errorMessage: String?) { showToast(errorMessage!!, Toast.LENGTH_LONG) binding.llLogin.visibility = View.VISIBLE } - override fun showUsernameError(error: String?) { + private fun showUsernameError(error: String?) { binding.tilUsername.error = error } - override fun showPasswordError(error: String?) { + private fun showPasswordError(error: String?) { binding.tilPassword.error = error } - override fun clearUsernameError() { + private fun clearUsernameError() { binding.tilUsername.isErrorEnabled = false } - override fun clearPasswordError() { + private fun clearPasswordError() { binding.tilPassword.isErrorEnabled = false } @@ -134,26 +177,89 @@ class LoginActivity : BaseActivity(), LoginView { * Called when Login Button is clicked, used for logging in the user */ - fun onLoginClicked() { + private fun onLoginClicked() { val username = binding.tilUsername.editText?.editableText.toString() val password = binding.tilPassword.editText?.editableText.toString() if (Network.isConnected(this)) { - val payload = LoginPayload() - payload.username = username - payload.password = password - loginPresenter?.login(payload) + if (isCredentialsValid(username, password)) + viewModel.login(username, password) } else { Toaster.show(binding.llLogin, getString(R.string.no_internet_connection)) } } - fun onRegisterClicked() { - startActivity(Intent(this@LoginActivity, RegistrationActivity::class.java)) + private fun isCredentialsValid(username: String, password: String): Boolean { + var credentialValid = true + val resources = context?.resources + when { + viewModel.isFieldEmpty(username) -> { + showUsernameError( + context?.getString( + R.string.error_validation_blank, + context?.getString(R.string.username), + ), + ) + credentialValid = false + } + + viewModel.isUsernameLengthInadequate(username) -> { + showUsernameError( + context?.getString( + R.string.error_validation_minimum_chars, + resources?.getString(R.string.username), + resources?.getInteger(R.integer.username_minimum_length), + ), + ) + credentialValid = false + } + + viewModel.usernameHasSpaces(username) -> { + showUsernameError( + context?.getString( + R.string.error_validation_cannot_contain_spaces, + resources?.getString(R.string.username), + context?.getString(R.string.not_contain_username), + ), + ) + credentialValid = false + } + + else -> { + clearUsernameError() + } + } + + when { + viewModel.isFieldEmpty(password) -> { + showPasswordError( + context?.getString( + R.string.error_validation_blank, + context?.getString(R.string.password), + ), + ) + credentialValid = false + } + + viewModel.isPasswordLengthInadequate(password) -> { + showPasswordError( + context?.getString( + R.string.error_validation_minimum_chars, + resources?.getString(R.string.password), + resources?.getInteger(R.integer.password_minimum_length), + ), + ) + credentialValid = false + } + + else -> { + clearPasswordError() + } + } + return credentialValid } - override fun onDestroy() { - super.onDestroy() - loginPresenter?.detachView() + private fun onRegisterClicked() { + startActivity(Intent(this@LoginActivity, RegistrationActivity::class.java)) } /** diff --git a/app/src/main/java/org/mifos/mobile/utils/LoginUiState.kt b/app/src/main/java/org/mifos/mobile/utils/LoginUiState.kt new file mode 100644 index 000000000..477664d75 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/utils/LoginUiState.kt @@ -0,0 +1,13 @@ +package org.mifos.mobile.utils + +sealed class LoginUiState { + data class DynamicError(val errorMessage: String) : LoginUiState() + object ServerDownError : LoginUiState() + object DuringLoginError : LoginUiState() + object LoginSuccess : LoginUiState() + object Loading : LoginUiState() + object UnauthorisedClientError : LoginUiState() + object FetchingClientError : LoginUiState() + object ClientNotFoundError : LoginUiState() + data class LoadClientSuccess(val clientName: String?) : LoginUiState() +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/LoginViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/LoginViewModel.kt new file mode 100644 index 000000000..1ddc48c9b --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/viewModels/LoginViewModel.kt @@ -0,0 +1,123 @@ +package org.mifos.mobile.viewModels + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.observers.DisposableObserver +import io.reactivex.plugins.RxJavaPlugins +import io.reactivex.schedulers.Schedulers +import org.mifos.mobile.models.Page +import org.mifos.mobile.models.User +import org.mifos.mobile.models.client.Client +import org.mifos.mobile.repositories.UserAuthRepository +import org.mifos.mobile.utils.LoginUiState +import retrofit2.HttpException +import java.net.UnknownHostException +import javax.inject.Inject + +@HiltViewModel +class LoginViewModel @Inject constructor(private val userAuthRepositoryImp: UserAuthRepository) : + ViewModel() { + + private val compositeDisposable = CompositeDisposable() + private var _loginUiState = MutableLiveData() + val loginUiState: LiveData get() = _loginUiState + + fun isFieldEmpty(fieldText: String): Boolean { + return fieldText.isEmpty() + } + + fun isUsernameLengthInadequate(username: String): Boolean { + return username.length < 5 + } + + fun isPasswordLengthInadequate(password: String): Boolean { + return password.length < 6 + } + + fun usernameHasSpaces(username: String): Boolean { + return username.trim().contains(" ") + } + + /** + * This method attempts to authenticate the user from + * the server and then persist the authentication data if we successfully + * authenticate the credentials or notify about any errors. + */ + fun login(username: String, password: String) { + _loginUiState.value = LoginUiState.Loading + compositeDisposable.add( + userAuthRepositoryImp.login(username, password) + ?.observeOn(AndroidSchedulers.mainThread())?.subscribeOn(Schedulers.io())!! + .subscribeWith(object : DisposableObserver() { + override fun onComplete() {} + override fun onError(e: Throwable) { + try { + if (e is HttpException) { + if (e.code() == 503) { + _loginUiState.value = LoginUiState.ServerDownError + } else { + _loginUiState.value = + LoginUiState.DynamicError(e.response().errorBody().string()) + } + } + if (e is UnknownHostException) { + _loginUiState.value = LoginUiState.DuringLoginError + } + } catch (throwable: Throwable) { + RxJavaPlugins.getErrorHandler() + } + } + + override fun onNext(user: User) { + userAuthRepositoryImp.saveAuthenticationTokenForSession(user) + _loginUiState.value = LoginUiState.LoginSuccess + } + }), + ) + } + + /** + * This method fetches the Client, associated with current Access Token. + */ + fun loadClient() { + userAuthRepositoryImp.loadClient()?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribeOn(Schedulers.io()) + ?.subscribeWith(object : DisposableObserver?>() { + override fun onComplete() {} + override fun onError(e: Throwable) { + if ((e as HttpException).code() == 401) { + _loginUiState.value = LoginUiState.UnauthorisedClientError + } else { + _loginUiState.value = LoginUiState.FetchingClientError + } + userAuthRepositoryImp.clearPrefHelper() + userAuthRepositoryImp.reInitializeService() + } + + override fun onNext(clientPage: Page) { + if (clientPage.pageItems.isNotEmpty()) { + val clientId = clientPage.pageItems[0]?.id?.toLong() + val clientName = clientPage.pageItems[0]?.displayName + userAuthRepositoryImp.setClientId(clientId) + userAuthRepositoryImp.reInitializeService() + _loginUiState.value = LoginUiState.LoadClientSuccess(clientName) + } else { + _loginUiState.value = LoginUiState.ClientNotFoundError + } + } + })?.let { + compositeDisposable.add( + it, + ) + } + } + + override fun onCleared() { + super.onCleared() + compositeDisposable.clear() + } +} \ No newline at end of file From 4b5b0f4f4baef1b750bb3952db8005603c975674 Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Sat, 8 Jul 2023 00:53:28 +0530 Subject: [PATCH 23/35] feat : login activity mvvm migration -> modified Ui state class -> added unit tests for LoginViewModel --- .../mobile/ui/activities/LoginActivity.kt | 30 +-- .../org/mifos/mobile/utils/LoginUiState.kt | 7 +- .../mifos/mobile/viewModels/LoginViewModel.kt | 22 +-- app/src/main/res/values-ar/strings.xml | 1 + app/src/main/res/values-bn/strings.xml | 1 + app/src/main/res/values-es/strings.xml | 1 + app/src/main/res/values-fa-rAF/strings.xml | 1 + app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values-hi/strings.xml | 1 + app/src/main/res/values-in/strings.xml | 1 + app/src/main/res/values-km/strings.xml | 1 + app/src/main/res/values-kn/strings.xml | 1 + app/src/main/res/values-my/strings.xml | 1 + app/src/main/res/values-pl/strings.xml | 1 + app/src/main/res/values-pt/strings.xml | 1 + app/src/main/res/values-ru/strings.xml | 1 + app/src/main/res/values-sw/strings.xml | 1 + app/src/main/res/values-te/strings.xml | 1 + app/src/main/res/values-ur/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + .../mobile/viewModels/LoginViewModelTest.kt | 172 ++++++++++++++++++ 21 files changed, 195 insertions(+), 53 deletions(-) create mode 100644 app/src/test/java/org/mifos/mobile/viewModels/LoginViewModelTest.kt diff --git a/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt b/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt index c7b863ea8..82b7b0cb1 100644 --- a/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt +++ b/app/src/main/java/org/mifos/mobile/ui/activities/LoginActivity.kt @@ -14,7 +14,6 @@ import org.mifos.mobile.databinding.ActivityLoginBinding import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.utils.Constants import org.mifos.mobile.utils.LoginUiState -import org.mifos.mobile.utils.MFErrorParser import org.mifos.mobile.utils.Network import org.mifos.mobile.utils.Toaster import org.mifos.mobile.viewModels.LoginViewModel @@ -53,40 +52,15 @@ class LoginActivity : BaseActivity() { when (state) { LoginUiState.Loading -> showProgress() - LoginUiState.DuringLoginError -> { + LoginUiState.Error -> { hideProgress() - showMessage(context?.getString(R.string.err_during_login)) - } - - LoginUiState.ServerDownError -> { - hideProgress() - showMessage(context?.getString(R.string.error_server_down)) + showMessage(context?.getString(R.string.login_failed)) } LoginUiState.LoginSuccess -> { onLoginSuccess() } - is LoginUiState.DynamicError -> { - hideProgress() - showMessage(MFErrorParser.parseError(state.errorMessage).developerMessage) - } - - LoginUiState.UnauthorisedClientError -> { - hideProgress() - showMessage(context?.getString(R.string.unauthorized_client)) - } - - LoginUiState.FetchingClientError -> { - hideProgress() - showMessage(context?.getString(R.string.error_fetching_client)) - } - - LoginUiState.ClientNotFoundError -> { - hideProgress() - showMessage(context?.getString(R.string.error_client_not_found)) - } - is LoginUiState.LoadClientSuccess -> { hideProgress() showPassCodeActivity(state.clientName) diff --git a/app/src/main/java/org/mifos/mobile/utils/LoginUiState.kt b/app/src/main/java/org/mifos/mobile/utils/LoginUiState.kt index 477664d75..c3404e965 100644 --- a/app/src/main/java/org/mifos/mobile/utils/LoginUiState.kt +++ b/app/src/main/java/org/mifos/mobile/utils/LoginUiState.kt @@ -1,13 +1,8 @@ package org.mifos.mobile.utils sealed class LoginUiState { - data class DynamicError(val errorMessage: String) : LoginUiState() - object ServerDownError : LoginUiState() - object DuringLoginError : LoginUiState() object LoginSuccess : LoginUiState() object Loading : LoginUiState() - object UnauthorisedClientError : LoginUiState() - object FetchingClientError : LoginUiState() - object ClientNotFoundError : LoginUiState() + object Error : LoginUiState() data class LoadClientSuccess(val clientName: String?) : LoginUiState() } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/LoginViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/LoginViewModel.kt index 1ddc48c9b..148ab88dc 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/LoginViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/LoginViewModel.kt @@ -14,8 +14,6 @@ import org.mifos.mobile.models.User import org.mifos.mobile.models.client.Client import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.utils.LoginUiState -import retrofit2.HttpException -import java.net.UnknownHostException import javax.inject.Inject @HiltViewModel @@ -56,17 +54,7 @@ class LoginViewModel @Inject constructor(private val userAuthRepositoryImp: User override fun onComplete() {} override fun onError(e: Throwable) { try { - if (e is HttpException) { - if (e.code() == 503) { - _loginUiState.value = LoginUiState.ServerDownError - } else { - _loginUiState.value = - LoginUiState.DynamicError(e.response().errorBody().string()) - } - } - if (e is UnknownHostException) { - _loginUiState.value = LoginUiState.DuringLoginError - } + _loginUiState.value = LoginUiState.Error } catch (throwable: Throwable) { RxJavaPlugins.getErrorHandler() } @@ -89,11 +77,7 @@ class LoginViewModel @Inject constructor(private val userAuthRepositoryImp: User ?.subscribeWith(object : DisposableObserver?>() { override fun onComplete() {} override fun onError(e: Throwable) { - if ((e as HttpException).code() == 401) { - _loginUiState.value = LoginUiState.UnauthorisedClientError - } else { - _loginUiState.value = LoginUiState.FetchingClientError - } + _loginUiState.value = LoginUiState.Error userAuthRepositoryImp.clearPrefHelper() userAuthRepositoryImp.reInitializeService() } @@ -106,7 +90,7 @@ class LoginViewModel @Inject constructor(private val userAuthRepositoryImp: User userAuthRepositoryImp.reInitializeService() _loginUiState.value = LoginUiState.LoadClientSuccess(clientName) } else { - _loginUiState.value = LoginUiState.ClientNotFoundError + _loginUiState.value = LoginUiState.Error } } })?.let { diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index edc555e98..61822c86e 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -443,4 +443,5 @@ أدخل المستأجر معلومات التطبيق إظهار أو إخفاء إجمالي مبلغ التوفير + فشل تسجيل الدخول يرجى المحاولة مرة أخرى في وقت لاحق. \ No newline at end of file diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index e8c26a315..47abea6ed 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -430,4 +430,5 @@ অ্যাপের তথ্য মোট সঞ্চয় পরিমাণ দেখান বা লুকান + পরে আবার চেষ্টা করুন ব্যর্থ লগইন. diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 361eeebc1..6c7b6926e 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -419,4 +419,5 @@ Introduce la URL principal Ir al inquilino Informacion de la applicacion + No se pudo entrar Inténtelo más tarde. \ No newline at end of file diff --git a/app/src/main/res/values-fa-rAF/strings.xml b/app/src/main/res/values-fa-rAF/strings.xml index 153b6548d..dafd90586 100644 --- a/app/src/main/res/values-fa-rAF/strings.xml +++ b/app/src/main/res/values-fa-rAF/strings.xml @@ -424,4 +424,5 @@ کار کردن بلي اطلاعات برنامه + ورود ناموفق بود، لطفاً بعداً دوباره امتحان کنید. \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index fe485ee9e..a6d805667 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -417,4 +417,5 @@ Aller au locataire Informations sur l\'application Afficher ou masquer le montant total de l\'épargne + Authentification échouée, essayez plus tard. \ No newline at end of file diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index f21034cb6..8c30105ea 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -392,6 +392,7 @@ कृपया प्रतीक्षा करें अनुप्रयोग की जानकारी + विफल प्रवेश कृपया बाद में पुन: प्रयास करें। \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 32110188f..2ff5c0a01 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -418,4 +418,5 @@ Masukkan URL utama Pergi ke Tenant Info Aplikasi + Login Gagal, Silakan Coba Lagi Nanti. diff --git a/app/src/main/res/values-km/strings.xml b/app/src/main/res/values-km/strings.xml index e13020ec1..26f849c2d 100644 --- a/app/src/main/res/values-km/strings.xml +++ b/app/src/main/res/values-km/strings.xml @@ -418,4 +418,5 @@ បញ្ចូល URL ចម្បង ចូលទៅកាន់ភតិកៈ ព័ត៌មានកម្មវិធី + ការចូលបានបរាជ័យ សូមព្យាយាមម្តងទៀតនៅពេលក្រោយ។ diff --git a/app/src/main/res/values-kn/strings.xml b/app/src/main/res/values-kn/strings.xml index 866f53f1d..f18dc2a09 100644 --- a/app/src/main/res/values-kn/strings.xml +++ b/app/src/main/res/values-kn/strings.xml @@ -418,4 +418,5 @@ ಪ್ರಾಥಮಿಕ URL ಅನ್ನು ನಮೂದಿಸಿ ಟೆನಂಟ್ಗೆ ಹೋಗಿ ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ + ಲಾಗಿನ್ ವಿಫಲವಾಗಿದೆ ದಯವಿಟ್ಟು ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ. diff --git a/app/src/main/res/values-my/strings.xml b/app/src/main/res/values-my/strings.xml index 2443df7ef..9c72693d2 100644 --- a/app/src/main/res/values-my/strings.xml +++ b/app/src/main/res/values-my/strings.xml @@ -441,5 +441,6 @@ ဥယျာဉ်စောင့် Enter အက်ပ်အချက်အလက် စုစုပေါင်းချွေတာသည့်ပမာဏကို ပြပါ သို့မဟုတ် ဝှက်ပါ။ + အကောင့်ဝင်ခြင်း မအောင်မြင်ပါ၊ ကျေးဇူးပြု၍ နောက်မှ ထပ်စမ်းကြည့်ပါ။ \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index d4fbf0f8a..d803e609f 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -419,4 +419,5 @@ Wprowadź podstawowy adres URL Wejdź do Lokatora Informacje o aplikacji + Zły login, proszę spróbować ponownie. diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 46dd622bc..78fefe25c 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -502,5 +502,6 @@ accountType.loan Erro ao carregar em detalhes de contas de empréstimo Informações do aplicativo + O login falhou por favor tente novamente mais tarde. diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 6fe04625f..b4c165bba 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -419,4 +419,5 @@ Введите основной URL-адрес Перейти к Арендатору Информация о приложении + Войти не удалось, пожалуйста, повторите попытку позже. \ No newline at end of file diff --git a/app/src/main/res/values-sw/strings.xml b/app/src/main/res/values-sw/strings.xml index ec7d97b7b..7dca8a32f 100644 --- a/app/src/main/res/values-sw/strings.xml +++ b/app/src/main/res/values-sw/strings.xml @@ -418,4 +418,5 @@ Ingiza URL ya msingi Nenda kwa Mpangaji Maelezo ya Programu + Kuingia Kumeshindwa, Tafadhali Jaribu Tena Baadaye. \ No newline at end of file diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index 523d61cda..b1a669acf 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -419,4 +419,5 @@ బేస్ URL ను నమోదు చేయండి అద్దెదారు నమోదు చేయండి యాప్ సమాచారం + లాగిన్ విఫలమైంది, దయచేసి తర్వాత మళ్లీ ప్రయత్నించండి. \ No newline at end of file diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index c79390404..0644c048c 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -440,5 +440,6 @@ بیس یو آر ایل درج کریں کرایہ درج کریں ایپ کی معلومات + لاگ ان ناکام ہوگیا، براہ کرم بعد میں دوبارہ کوشش کریں۔ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1807a635c..7ce29f1a9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -645,5 +645,6 @@ Dark Theme App Info + Login Failed, Please Try Again Later. diff --git a/app/src/test/java/org/mifos/mobile/viewModels/LoginViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/LoginViewModelTest.kt new file mode 100644 index 000000000..30cb4213c --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/viewModels/LoginViewModelTest.kt @@ -0,0 +1,172 @@ +package org.mifos.mobile.viewModels + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import androidx.lifecycle.Observer +import io.reactivex.Observable + +import org.junit.After +import org.junit.Assert +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mifos.mobile.FakeRemoteDataSource +import org.mifos.mobile.models.Page +import org.mifos.mobile.models.User +import org.mifos.mobile.models.client.Client +import org.mifos.mobile.repositories.UserAuthRepository +import org.mifos.mobile.util.RxSchedulersOverrideRule +import org.mifos.mobile.utils.LoginUiState +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import java.lang.RuntimeException + +class LoginViewModelTest { + + @JvmField + @Rule + val mOverrideSchedulersRule = RxSchedulersOverrideRule() + + @get:Rule + val rule = InstantTaskExecutorRule() + + @Mock + lateinit var userAuthRepositoryImp : UserAuthRepository + + @Mock + lateinit var loginUiStateObserver : Observer + + private lateinit var mockUser : User + private lateinit var loginViewModel : LoginViewModel + private var emptyClientPage : Page? = null + private var clientPage : Page? = null + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + loginViewModel = LoginViewModel(userAuthRepositoryImp) + loginViewModel.loginUiState.observeForever(loginUiStateObserver) + mockUser = FakeRemoteDataSource.user + emptyClientPage = FakeRemoteDataSource.noClients + clientPage = FakeRemoteDataSource.clients + } + + @Test + fun testIsFieldEmpty_WithNonEmptyStringInput_ReturnsFalse() { + val result = loginViewModel.isFieldEmpty("nonEmptyTestString") + Assert.assertFalse(result) + } + + @Test + fun testIsFieldEmpty_WithEmptyStringInput_ReturnsTrue() { + val result = loginViewModel.isFieldEmpty("") + Assert.assertTrue(result) + } + + @Test + fun testIsUsernameLengthInadequate_WithAdequateLengthInput_ReturnsFalse() { + val result = loginViewModel.isUsernameLengthInadequate("username123") + Assert.assertFalse(result) + } + + @Test + fun testIsUsernameLengthInadequate_WithInadequateLengthInput_ReturnsTrue() { + val result = loginViewModel.isUsernameLengthInadequate("user") + Assert.assertTrue(result) + } + + @Test + fun testIsPasswordLengthInadequate_WithAdequateLengthInput_ReturnsFalse() { + val result = loginViewModel.isUsernameLengthInadequate("password123") + Assert.assertFalse(result) + } + + @Test + fun testIsPasswordLengthInadequate_WithInadequateLengthInput_ReturnsTrue() { + val result = loginViewModel.isUsernameLengthInadequate("pass") + Assert.assertTrue(result) + } + + @Test + fun testUsernameHasSpaces_WithSpacesInput_ReturnsTrue() { + val result = loginViewModel.usernameHasSpaces("username withSpace") + Assert.assertTrue(result) + } + + @Test + fun testUsernameHasSpaces_WithNoSpacesInput_ReturnsFalse() { + val result = loginViewModel.usernameHasSpaces("usernameNoSpaces") + Assert.assertFalse(result) + } + + @Test + fun testLogin_SuccessfulLoginReceivedFromRepository_ReturnsLoginSuccess() { + Mockito.`when`( + userAuthRepositoryImp.login(Mockito.anyString(), Mockito.anyString()) + ).thenReturn(Observable.just(mockUser)) + + loginViewModel.login("username", "password") + + Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.Loading) + Mockito.verify(userAuthRepositoryImp).saveAuthenticationTokenForSession(mockUser) + Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.LoginSuccess) + } + + @Test + fun testLogin_UnsuccessfulLoginReceivedFromRepository_ReturnsError() { + val error = RuntimeException("Login Failed") + Mockito.`when`( + userAuthRepositoryImp.login(Mockito.anyString(), Mockito.anyString()) + ).thenReturn(Observable.error(error)) + + loginViewModel.login("username", "password") + + Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.Loading) + Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.Error) + } + + @Test + fun testLoadClient_UnsuccessfulLoadClientReceivedFromRepository_ReturnsError() { + val error = RuntimeException("Load Client Failed") + Mockito.`when`( + userAuthRepositoryImp.loadClient() + ).thenReturn(Observable.error(error)) + + loginViewModel.loadClient() + + Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.Error) + Mockito.verify(userAuthRepositoryImp).clearPrefHelper() + Mockito.verify(userAuthRepositoryImp).reInitializeService() + } + + @Test + fun testLoadClient_EmptyClientPageReceivedFromRepository_ReturnsError() { + Mockito.`when`( + userAuthRepositoryImp.loadClient() + ).thenReturn(Observable.just(emptyClientPage)) + + loginViewModel.loadClient() + + Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.Error) + } + + @Test + fun testLoadClient_NonEmptyClientPageReceivedFromRepository_ReturnsLoadClientSuccess() { + val clientId = clientPage?.pageItems?.get(0)?.id?.toLong() + val clientName = clientPage?.pageItems?.get(0)?.displayName + Mockito.`when`( + userAuthRepositoryImp.loadClient() + ).thenReturn(Observable.just(clientPage)) + + loginViewModel.loadClient() + + Mockito.verify(userAuthRepositoryImp).setClientId(clientId) + Mockito.verify(userAuthRepositoryImp).reInitializeService() + Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.LoadClientSuccess(clientName)) + } + + @After + fun tearDown() { + loginViewModel.loginUiState.removeObserver(loginUiStateObserver) + } +} \ No newline at end of file From 1af9aa034da56ff5a375a9818c01d4f95a225c7b Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Sat, 8 Jul 2023 18:18:55 +0530 Subject: [PATCH 24/35] feat : login activity mvvm migration -> updated LoginViewModel unit tests -> added unit tests for functions related to login feature in UserAuthRepositoryTest --- .../repositories/UserAuthRepositoryImpTest.kt | 71 ++++++++++++++++++- .../mobile/viewModels/LoginViewModelTest.kt | 8 +++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt b/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt index bd2b68744..475d0eb51 100644 --- a/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt +++ b/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt @@ -6,7 +6,12 @@ import org.junit.Assert import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.mifos.mobile.FakeRemoteDataSource import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.Page +import org.mifos.mobile.models.User +import org.mifos.mobile.models.client.Client +import org.mifos.mobile.models.payload.LoginPayload import org.mifos.mobile.models.register.RegisterPayload import org.mockito.Mock import org.mockito.Mockito @@ -19,12 +24,16 @@ class UserAuthRepositoryImpTest { @Mock lateinit var dataManager: DataManager - private lateinit var userAuthRepositoryImp: UserAuthRepositoryImp + private lateinit var userAuthRepositoryImp: UserAuthRepository + private lateinit var mockUser : User + private var mockClientPage : Page? = null @Before fun setUp() { MockitoAnnotations.openMocks(this) userAuthRepositoryImp = UserAuthRepositoryImp(dataManager) + mockUser = FakeRemoteDataSource.user + mockClientPage = FakeRemoteDataSource.clients } @Test @@ -89,4 +98,64 @@ class UserAuthRepositoryImpTest { Mockito.verify(dataManager).registerUser(registerPayload) Assert.assertEquals(result, error) } + + @Test + fun testLogin_SuccessResponseReceivedFromDataManager_ReturnsUserSuccessfully() { + val mockLoginPayload = LoginPayload().apply { + this.username = "username" + this.password = "password" + } + val successResponse : Observable = Observable.just(mockUser) + Mockito.`when`( + dataManager.login(mockLoginPayload) + ).thenReturn(successResponse) + + val result = userAuthRepositoryImp.login("username", "password") + + Mockito.verify(dataManager).login(mockLoginPayload) + Assert.assertEquals(result, successResponse) + } + + @Test + fun testLogin_ErrorResponseReceivedFromDataManager_ReturnsError() { + val mockLoginPayload = LoginPayload().apply { + this.username = "username" + this.password = "password" + } + val errorResponse : Observable = Observable.error(Throwable("Login Failed")) + Mockito.`when`( + dataManager.login(mockLoginPayload) + ).thenReturn(errorResponse) + + val result = userAuthRepositoryImp.login("username", "password") + + Mockito.verify(dataManager).login(mockLoginPayload) + Assert.assertEquals(result, errorResponse) + } + + @Test + fun testLoadClient_SuccessResponseReceivedFromDataManager_ReturnsClientPageSuccessfully() { + val successResponse : Observable?> = Observable.just(mockClientPage) + Mockito.`when`( + dataManager.clients + ).thenReturn(successResponse) + + val result = userAuthRepositoryImp.loadClient() + + Mockito.verify(dataManager).clients + Assert.assertEquals(result, successResponse) + } + + @Test + fun testLoadClient_ErrorResponseReceivedFromDataManager_ReturnsError() { + val errorResponse : Observable?> = Observable.error(Throwable("Load Client Failed")) + Mockito.`when`( + dataManager.clients + ).thenReturn(errorResponse) + + val result = userAuthRepositoryImp.loadClient() + + Mockito.verify(dataManager).clients + Assert.assertEquals(result, errorResponse) + } } \ No newline at end of file diff --git a/app/src/test/java/org/mifos/mobile/viewModels/LoginViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/LoginViewModelTest.kt index 30cb4213c..f99548f41 100644 --- a/app/src/test/java/org/mifos/mobile/viewModels/LoginViewModelTest.kt +++ b/app/src/test/java/org/mifos/mobile/viewModels/LoginViewModelTest.kt @@ -9,6 +9,7 @@ import org.junit.Assert import org.junit.Before import org.junit.Rule import org.junit.Test +import org.junit.runner.RunWith import org.mifos.mobile.FakeRemoteDataSource import org.mifos.mobile.models.Page import org.mifos.mobile.models.User @@ -19,8 +20,10 @@ import org.mifos.mobile.utils.LoginUiState import org.mockito.Mock import org.mockito.Mockito import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner import java.lang.RuntimeException +@RunWith(MockitoJUnitRunner::class) class LoginViewModelTest { @JvmField @@ -110,6 +113,7 @@ class LoginViewModelTest { Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.Loading) Mockito.verify(userAuthRepositoryImp).saveAuthenticationTokenForSession(mockUser) Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.LoginSuccess) + Mockito.verifyNoMoreInteractions(loginUiStateObserver) } @Test @@ -123,6 +127,7 @@ class LoginViewModelTest { Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.Loading) Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.Error) + Mockito.verifyNoMoreInteractions(loginUiStateObserver) } @Test @@ -137,6 +142,7 @@ class LoginViewModelTest { Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.Error) Mockito.verify(userAuthRepositoryImp).clearPrefHelper() Mockito.verify(userAuthRepositoryImp).reInitializeService() + Mockito.verifyNoMoreInteractions(loginUiStateObserver) } @Test @@ -148,6 +154,7 @@ class LoginViewModelTest { loginViewModel.loadClient() Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.Error) + Mockito.verifyNoMoreInteractions(loginUiStateObserver) } @Test @@ -163,6 +170,7 @@ class LoginViewModelTest { Mockito.verify(userAuthRepositoryImp).setClientId(clientId) Mockito.verify(userAuthRepositoryImp).reInitializeService() Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.LoadClientSuccess(clientName)) + Mockito.verifyNoMoreInteractions(loginUiStateObserver) } @After From afbcedcab25d0fd773139d220f2e800d5361dbb7 Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Mon, 10 Jul 2023 00:25:33 +0530 Subject: [PATCH 25/35] feat : login activity mvvm migration -> created ClientRepository, its implementation and unit tests. -> removed Client related methods from UserAuthRepository, and its unit tests. -> injected ClientRepositoryImp to LoginViewModel through Hilt, and added its entry to repository module of DI --- .../injection/module/RepositoryModule.kt | 7 +++ .../mobile/repositories/ClientRepository.kt | 19 ++++++ .../repositories/ClientRepositoryImp.kt | 52 +++++++++++++++++ .../mobile/repositories/UserAuthRepository.kt | 13 ----- .../repositories/UserAuthRepositoryImp.kt | 42 -------------- .../mifos/mobile/viewModels/LoginViewModel.kt | 18 +++--- .../repositories/ClientRepositoryImpTest.kt | 58 +++++++++++++++++++ .../repositories/UserAuthRepositoryImpTest.kt | 31 +--------- .../mobile/viewModels/LoginViewModelTest.kt | 22 ++++--- 9 files changed, 161 insertions(+), 101 deletions(-) create mode 100644 app/src/main/java/org/mifos/mobile/repositories/ClientRepository.kt create mode 100644 app/src/main/java/org/mifos/mobile/repositories/ClientRepositoryImp.kt create mode 100644 app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt diff --git a/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt index 2063047cc..fcff89769 100644 --- a/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt +++ b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt @@ -5,6 +5,8 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import org.mifos.mobile.api.DataManager +import org.mifos.mobile.repositories.ClientRepository +import org.mifos.mobile.repositories.ClientRepositoryImp import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.repositories.UserAuthRepositoryImp @@ -16,4 +18,9 @@ class RepositoryModule { fun providesUserAuthRepository(dataManager: DataManager): UserAuthRepository { return UserAuthRepositoryImp(dataManager) } + + @Provides + fun providesClientRepository(dataManager: DataManager): ClientRepository { + return ClientRepositoryImp(dataManager) + } } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/ClientRepository.kt b/app/src/main/java/org/mifos/mobile/repositories/ClientRepository.kt new file mode 100644 index 000000000..78997092c --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/repositories/ClientRepository.kt @@ -0,0 +1,19 @@ +package org.mifos.mobile.repositories + +import io.reactivex.Observable +import org.mifos.mobile.models.Page +import org.mifos.mobile.models.User +import org.mifos.mobile.models.client.Client + +interface ClientRepository { + + fun loadClient() : Observable?>? + + fun saveAuthenticationTokenForSession(user: User) + + fun reInitializeService() + + fun setClientId(clientId: Long?) + + fun clearPrefHelper() +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/ClientRepositoryImp.kt b/app/src/main/java/org/mifos/mobile/repositories/ClientRepositoryImp.kt new file mode 100644 index 000000000..1aea2934e --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/repositories/ClientRepositoryImp.kt @@ -0,0 +1,52 @@ +package org.mifos.mobile.repositories + +import io.reactivex.Observable +import org.mifos.mobile.api.BaseApiManager +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.Page +import org.mifos.mobile.models.User +import org.mifos.mobile.models.client.Client +import org.mifos.mobile.utils.Constants +import javax.inject.Inject + +class ClientRepositoryImp @Inject constructor(private val dataManager: DataManager) : + ClientRepository { + + private val preferencesHelper = dataManager.preferencesHelper + + override fun loadClient(): Observable?>? { + return dataManager.clients + } + + /** + * Save the authentication token from the server and the user ID. + * The authentication token would be used for accessing the authenticated + * APIs. + * + * @param user - The user that is to be saved. + */ + override fun saveAuthenticationTokenForSession(user: User) { + val authToken = Constants.BASIC + user.base64EncodedAuthenticationKey + preferencesHelper.userName = user.username + preferencesHelper.userId = user.userId + preferencesHelper.saveToken(authToken) + reInitializeService() + } + + override fun reInitializeService() { + BaseApiManager.createService( + preferencesHelper.baseUrl, + preferencesHelper.tenant, + preferencesHelper.token, + ) + } + + override fun setClientId(clientId: Long?) { + preferencesHelper.clientId = clientId + dataManager.clientId = clientId + } + + override fun clearPrefHelper() { + preferencesHelper.clear() + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt index 05464116a..0849e797f 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt @@ -2,9 +2,7 @@ package org.mifos.mobile.repositories import io.reactivex.Observable import okhttp3.ResponseBody -import org.mifos.mobile.models.Page import org.mifos.mobile.models.User -import org.mifos.mobile.models.client.Client interface UserAuthRepository { @@ -20,15 +18,4 @@ interface UserAuthRepository { ): Observable? fun login(username: String, password: String): Observable? - - fun loadClient() : Observable?>? - - fun saveAuthenticationTokenForSession(user: User) - - fun reInitializeService() - - fun setClientId(clientId: Long?) - - fun clearPrefHelper() - } diff --git a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt index e0d2fb6c3..6fe9b834a 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt @@ -2,21 +2,15 @@ package org.mifos.mobile.repositories import io.reactivex.Observable import okhttp3.ResponseBody -import org.mifos.mobile.api.BaseApiManager import org.mifos.mobile.api.DataManager -import org.mifos.mobile.models.Page import org.mifos.mobile.models.User -import org.mifos.mobile.models.client.Client import org.mifos.mobile.models.payload.LoginPayload import org.mifos.mobile.models.register.RegisterPayload -import org.mifos.mobile.utils.Constants import javax.inject.Inject class UserAuthRepositoryImp @Inject constructor(private val dataManager: DataManager) : UserAuthRepository { - private val preferencesHelper = dataManager.preferencesHelper - override fun registerUser( accountNumber: String?, authenticationMode: String?, @@ -48,40 +42,4 @@ class UserAuthRepositoryImp @Inject constructor(private val dataManager: DataMan return dataManager.login(loginPayload) } - override fun loadClient(): Observable?>? { - return dataManager.clients - } - - /** - * Save the authentication token from the server and the user ID. - * The authentication token would be used for accessing the authenticated - * APIs. - * - * @param userID - The userID of the user to be saved. - * @param authToken - The authentication token to be saved. - */ - override fun saveAuthenticationTokenForSession(user: User) { - val authToken = Constants.BASIC + user.base64EncodedAuthenticationKey - preferencesHelper.userName = user.username - preferencesHelper.userId = user.userId - preferencesHelper.saveToken(authToken) - reInitializeService() - } - - override fun reInitializeService() { - BaseApiManager.createService( - preferencesHelper.baseUrl, - preferencesHelper.tenant, - preferencesHelper.token, - ) - } - - override fun setClientId(clientId: Long?) { - preferencesHelper.clientId = clientId - dataManager.clientId = clientId - } - - override fun clearPrefHelper() { - preferencesHelper.clear() - } } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/LoginViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/LoginViewModel.kt index 148ab88dc..58df63636 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/LoginViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/LoginViewModel.kt @@ -12,12 +12,16 @@ import io.reactivex.schedulers.Schedulers import org.mifos.mobile.models.Page import org.mifos.mobile.models.User import org.mifos.mobile.models.client.Client +import org.mifos.mobile.repositories.ClientRepository import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.utils.LoginUiState import javax.inject.Inject @HiltViewModel -class LoginViewModel @Inject constructor(private val userAuthRepositoryImp: UserAuthRepository) : +class LoginViewModel @Inject constructor( + private val userAuthRepositoryImp: UserAuthRepository, + private val clientRepositoryImp: ClientRepository +) : ViewModel() { private val compositeDisposable = CompositeDisposable() @@ -61,7 +65,7 @@ class LoginViewModel @Inject constructor(private val userAuthRepositoryImp: User } override fun onNext(user: User) { - userAuthRepositoryImp.saveAuthenticationTokenForSession(user) + clientRepositoryImp.saveAuthenticationTokenForSession(user) _loginUiState.value = LoginUiState.LoginSuccess } }), @@ -72,22 +76,22 @@ class LoginViewModel @Inject constructor(private val userAuthRepositoryImp: User * This method fetches the Client, associated with current Access Token. */ fun loadClient() { - userAuthRepositoryImp.loadClient()?.observeOn(AndroidSchedulers.mainThread()) + clientRepositoryImp.loadClient()?.observeOn(AndroidSchedulers.mainThread()) ?.subscribeOn(Schedulers.io()) ?.subscribeWith(object : DisposableObserver?>() { override fun onComplete() {} override fun onError(e: Throwable) { _loginUiState.value = LoginUiState.Error - userAuthRepositoryImp.clearPrefHelper() - userAuthRepositoryImp.reInitializeService() + clientRepositoryImp.clearPrefHelper() + clientRepositoryImp.reInitializeService() } override fun onNext(clientPage: Page) { if (clientPage.pageItems.isNotEmpty()) { val clientId = clientPage.pageItems[0]?.id?.toLong() val clientName = clientPage.pageItems[0]?.displayName - userAuthRepositoryImp.setClientId(clientId) - userAuthRepositoryImp.reInitializeService() + clientRepositoryImp.setClientId(clientId) + clientRepositoryImp.reInitializeService() _loginUiState.value = LoginUiState.LoadClientSuccess(clientName) } else { _loginUiState.value = LoginUiState.Error diff --git a/app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt b/app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt new file mode 100644 index 000000000..db512add5 --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt @@ -0,0 +1,58 @@ +package org.mifos.mobile.repositories + +import io.reactivex.Observable +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mifos.mobile.FakeRemoteDataSource +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.Page +import org.mifos.mobile.models.client.Client +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner + +@RunWith(MockitoJUnitRunner::class) +class ClientRepositoryImpTest { + + @Mock + lateinit var dataManager: DataManager + private var mockClientPage: Page? = null + private lateinit var clientRepositoryImp: ClientRepositoryImp + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + clientRepositoryImp = ClientRepositoryImp(dataManager) + mockClientPage = FakeRemoteDataSource.clients + } + + @Test + fun testLoadClient_SuccessResponseReceivedFromDataManager_ReturnsClientPageSuccessfully() { + val successResponse: Observable?> = Observable.just(mockClientPage) + Mockito.`when`( + dataManager.clients + ).thenReturn(successResponse) + + val result = clientRepositoryImp.loadClient() + + Mockito.verify(dataManager).clients + Assert.assertEquals(result, successResponse) + } + + @Test + fun testLoadClient_ErrorResponseReceivedFromDataManager_ReturnsError() { + val errorResponse: Observable?> = + Observable.error(Throwable("Load Client Failed")) + Mockito.`when`( + dataManager.clients + ).thenReturn(errorResponse) + + val result = clientRepositoryImp.loadClient() + + Mockito.verify(dataManager).clients + Assert.assertEquals(result, errorResponse) + } +} \ No newline at end of file diff --git a/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt b/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt index 475d0eb51..374fc37d1 100644 --- a/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt +++ b/app/src/test/java/org/mifos/mobile/repositories/UserAuthRepositoryImpTest.kt @@ -8,9 +8,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mifos.mobile.FakeRemoteDataSource import org.mifos.mobile.api.DataManager -import org.mifos.mobile.models.Page import org.mifos.mobile.models.User -import org.mifos.mobile.models.client.Client import org.mifos.mobile.models.payload.LoginPayload import org.mifos.mobile.models.register.RegisterPayload import org.mockito.Mock @@ -26,14 +24,13 @@ class UserAuthRepositoryImpTest { private lateinit var userAuthRepositoryImp: UserAuthRepository private lateinit var mockUser : User - private var mockClientPage : Page? = null + @Before fun setUp() { MockitoAnnotations.openMocks(this) userAuthRepositoryImp = UserAuthRepositoryImp(dataManager) mockUser = FakeRemoteDataSource.user - mockClientPage = FakeRemoteDataSource.clients } @Test @@ -132,30 +129,4 @@ class UserAuthRepositoryImpTest { Mockito.verify(dataManager).login(mockLoginPayload) Assert.assertEquals(result, errorResponse) } - - @Test - fun testLoadClient_SuccessResponseReceivedFromDataManager_ReturnsClientPageSuccessfully() { - val successResponse : Observable?> = Observable.just(mockClientPage) - Mockito.`when`( - dataManager.clients - ).thenReturn(successResponse) - - val result = userAuthRepositoryImp.loadClient() - - Mockito.verify(dataManager).clients - Assert.assertEquals(result, successResponse) - } - - @Test - fun testLoadClient_ErrorResponseReceivedFromDataManager_ReturnsError() { - val errorResponse : Observable?> = Observable.error(Throwable("Load Client Failed")) - Mockito.`when`( - dataManager.clients - ).thenReturn(errorResponse) - - val result = userAuthRepositoryImp.loadClient() - - Mockito.verify(dataManager).clients - Assert.assertEquals(result, errorResponse) - } } \ No newline at end of file diff --git a/app/src/test/java/org/mifos/mobile/viewModels/LoginViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/LoginViewModelTest.kt index f99548f41..f8934bb23 100644 --- a/app/src/test/java/org/mifos/mobile/viewModels/LoginViewModelTest.kt +++ b/app/src/test/java/org/mifos/mobile/viewModels/LoginViewModelTest.kt @@ -14,6 +14,7 @@ import org.mifos.mobile.FakeRemoteDataSource import org.mifos.mobile.models.Page import org.mifos.mobile.models.User import org.mifos.mobile.models.client.Client +import org.mifos.mobile.repositories.ClientRepository import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.util.RxSchedulersOverrideRule import org.mifos.mobile.utils.LoginUiState @@ -36,6 +37,9 @@ class LoginViewModelTest { @Mock lateinit var userAuthRepositoryImp : UserAuthRepository + @Mock + lateinit var clientRepositoryImp : ClientRepository + @Mock lateinit var loginUiStateObserver : Observer @@ -47,7 +51,7 @@ class LoginViewModelTest { @Before fun setUp() { MockitoAnnotations.openMocks(this) - loginViewModel = LoginViewModel(userAuthRepositoryImp) + loginViewModel = LoginViewModel(userAuthRepositoryImp, clientRepositoryImp) loginViewModel.loginUiState.observeForever(loginUiStateObserver) mockUser = FakeRemoteDataSource.user emptyClientPage = FakeRemoteDataSource.noClients @@ -111,7 +115,7 @@ class LoginViewModelTest { loginViewModel.login("username", "password") Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.Loading) - Mockito.verify(userAuthRepositoryImp).saveAuthenticationTokenForSession(mockUser) + Mockito.verify(clientRepositoryImp).saveAuthenticationTokenForSession(mockUser) Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.LoginSuccess) Mockito.verifyNoMoreInteractions(loginUiStateObserver) } @@ -134,21 +138,21 @@ class LoginViewModelTest { fun testLoadClient_UnsuccessfulLoadClientReceivedFromRepository_ReturnsError() { val error = RuntimeException("Load Client Failed") Mockito.`when`( - userAuthRepositoryImp.loadClient() + clientRepositoryImp.loadClient() ).thenReturn(Observable.error(error)) loginViewModel.loadClient() Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.Error) - Mockito.verify(userAuthRepositoryImp).clearPrefHelper() - Mockito.verify(userAuthRepositoryImp).reInitializeService() + Mockito.verify(clientRepositoryImp).clearPrefHelper() + Mockito.verify(clientRepositoryImp).reInitializeService() Mockito.verifyNoMoreInteractions(loginUiStateObserver) } @Test fun testLoadClient_EmptyClientPageReceivedFromRepository_ReturnsError() { Mockito.`when`( - userAuthRepositoryImp.loadClient() + clientRepositoryImp.loadClient() ).thenReturn(Observable.just(emptyClientPage)) loginViewModel.loadClient() @@ -162,13 +166,13 @@ class LoginViewModelTest { val clientId = clientPage?.pageItems?.get(0)?.id?.toLong() val clientName = clientPage?.pageItems?.get(0)?.displayName Mockito.`when`( - userAuthRepositoryImp.loadClient() + clientRepositoryImp.loadClient() ).thenReturn(Observable.just(clientPage)) loginViewModel.loadClient() - Mockito.verify(userAuthRepositoryImp).setClientId(clientId) - Mockito.verify(userAuthRepositoryImp).reInitializeService() + Mockito.verify(clientRepositoryImp).setClientId(clientId) + Mockito.verify(clientRepositoryImp).reInitializeService() Mockito.verify(loginUiStateObserver).onChanged(LoginUiState.LoadClientSuccess(clientName)) Mockito.verifyNoMoreInteractions(loginUiStateObserver) } From 81ba0d103012f898f4290b41e7a77f0a4fcb1a2f Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Mon, 10 Jul 2023 10:24:07 +0530 Subject: [PATCH 26/35] feat : login activity mvvm migration -> injected preferences helper dependency through hilt --- .../org/mifos/mobile/injection/module/RepositoryModule.kt | 7 +++++-- .../org/mifos/mobile/repositories/ClientRepositoryImp.kt | 8 ++++---- .../mifos/mobile/repositories/ClientRepositoryImpTest.kt | 7 ++++++- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt index fcff89769..5d6db0f61 100644 --- a/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt +++ b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt @@ -5,6 +5,7 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import org.mifos.mobile.api.DataManager +import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.repositories.ClientRepository import org.mifos.mobile.repositories.ClientRepositoryImp import org.mifos.mobile.repositories.UserAuthRepository @@ -20,7 +21,9 @@ class RepositoryModule { } @Provides - fun providesClientRepository(dataManager: DataManager): ClientRepository { - return ClientRepositoryImp(dataManager) + fun providesClientRepository( + dataManager: DataManager, preferencesHelper: PreferencesHelper + ): ClientRepository { + return ClientRepositoryImp(dataManager, preferencesHelper) } } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/ClientRepositoryImp.kt b/app/src/main/java/org/mifos/mobile/repositories/ClientRepositoryImp.kt index 1aea2934e..52a512989 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/ClientRepositoryImp.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/ClientRepositoryImp.kt @@ -3,16 +3,16 @@ package org.mifos.mobile.repositories import io.reactivex.Observable import org.mifos.mobile.api.BaseApiManager import org.mifos.mobile.api.DataManager +import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.models.Page import org.mifos.mobile.models.User import org.mifos.mobile.models.client.Client import org.mifos.mobile.utils.Constants import javax.inject.Inject -class ClientRepositoryImp @Inject constructor(private val dataManager: DataManager) : - ClientRepository { - - private val preferencesHelper = dataManager.preferencesHelper +class ClientRepositoryImp @Inject constructor( + private val dataManager: DataManager, private val preferencesHelper: PreferencesHelper +) : ClientRepository { override fun loadClient(): Observable?>? { return dataManager.clients diff --git a/app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt b/app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt index db512add5..2ee110dbe 100644 --- a/app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt +++ b/app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt @@ -7,6 +7,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mifos.mobile.FakeRemoteDataSource import org.mifos.mobile.api.DataManager +import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.models.Page import org.mifos.mobile.models.client.Client import org.mockito.Mock @@ -19,13 +20,17 @@ class ClientRepositoryImpTest { @Mock lateinit var dataManager: DataManager + + @Mock + lateinit var preferencesHelper: PreferencesHelper + private var mockClientPage: Page? = null private lateinit var clientRepositoryImp: ClientRepositoryImp @Before fun setUp() { MockitoAnnotations.openMocks(this) - clientRepositoryImp = ClientRepositoryImp(dataManager) + clientRepositoryImp = ClientRepositoryImp(dataManager, preferencesHelper) mockClientPage = FakeRemoteDataSource.clients } From e3ed04d9237bfc815d449cf90a59a41c35415526 Mon Sep 17 00:00:00 2001 From: Pratyush Singh Date: Mon, 10 Jul 2023 22:26:47 +0530 Subject: [PATCH 27/35] feat: Unit tests for viewmodel and repository --- .../RecentTransactionRepositoryImpTest.kt | 61 +++++++ .../RecentTransactionViewModelTest.kt | 163 ++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 app/src/test/java/org/mifos/mobile/repositories/RecentTransactionRepositoryImpTest.kt create mode 100644 app/src/test/java/org/mifos/mobile/viewModels/RecentTransactionViewModelTest.kt diff --git a/app/src/test/java/org/mifos/mobile/repositories/RecentTransactionRepositoryImpTest.kt b/app/src/test/java/org/mifos/mobile/repositories/RecentTransactionRepositoryImpTest.kt new file mode 100644 index 000000000..a90f8075c --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/repositories/RecentTransactionRepositoryImpTest.kt @@ -0,0 +1,61 @@ +package org.mifos.mobile.repositories + +import io.reactivex.Observable +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.Page +import org.mifos.mobile.models.Transaction +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner + + +@RunWith(MockitoJUnitRunner::class) +class RecentTransactionRepositoryImpTest { + + @Mock + lateinit var dataManager: DataManager + + private lateinit var recentTransactionRepositoryImp: RecentTransactionRepositoryImp + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + recentTransactionRepositoryImp = RecentTransactionRepositoryImp(dataManager) + } + + @Test + fun recentTransaction_successful_response_from_dataManger() { + val success: Observable?> = + Observable.just(Mockito.mock(Page()::class.java)) + val offset = 0 + val limit = 50 + + Mockito.`when`(dataManager.getRecentTransactions(offset, limit)).thenReturn(success) + + val result = recentTransactionRepositoryImp.recentTransactions(offset, limit) + + Mockito.verify(dataManager).getRecentTransactions(offset, limit) + Assert.assertEquals(result, success) + } + + @Test + fun recentTransaction_unsuccessful_response_from_dataManger() { + val error: Observable?> = + Observable.error(Throwable("Recent Transaction Failed")) + val offset = 0 + val limit = 50 + + Mockito.`when`(dataManager.getRecentTransactions(offset, limit)).thenReturn(error) + + val result = recentTransactionRepositoryImp.recentTransactions(offset, limit) + + Mockito.verify(dataManager).getRecentTransactions(offset, limit) + Assert.assertEquals(result, error) + } + +} \ No newline at end of file diff --git a/app/src/test/java/org/mifos/mobile/viewModels/RecentTransactionViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/RecentTransactionViewModelTest.kt new file mode 100644 index 000000000..aab9329ff --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/viewModels/RecentTransactionViewModelTest.kt @@ -0,0 +1,163 @@ +package org.mifos.mobile.viewModels + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import androidx.lifecycle.Observer +import io.reactivex.Observable +import org.junit.* +import org.junit.runner.RunWith +import org.mifos.mobile.models.Page +import org.mifos.mobile.models.Transaction +import org.mifos.mobile.models.client.Currency +import org.mifos.mobile.models.client.Type +import org.mifos.mobile.repositories.RecentTransactionRepository +import org.mifos.mobile.util.RxSchedulersOverrideRule +import org.mifos.mobile.utils.RecentTransactionUiState +import org.mockito.Mock +import org.mockito.Mockito.* +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner +import org.mifos.mobile.R + +@RunWith(MockitoJUnitRunner::class) +class RecentTransactionViewModelTest { + + @JvmField + @Rule + val mOverrideSchedulersRule = RxSchedulersOverrideRule() + + @get:Rule + val rule = InstantTaskExecutorRule() + + @Mock + lateinit var recentTransactionRepositoryImp: RecentTransactionRepository + + @Mock + lateinit var recentTransactionUiStateObserver: Observer + + @Mock + lateinit var type: Type + + @Mock + lateinit var currency: Currency + + lateinit var viewModel: RecentTransactionViewModel + + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + viewModel = RecentTransactionViewModel(recentTransactionRepositoryImp) + viewModel.recentTransactionUiState.observeForever(recentTransactionUiStateObserver) + } + + @Test + fun loadRecentTransaction_success_with_no_empty_transactions() { + val offset = 0 + val limit = 50 + + val transaction = Transaction( + id = 1L, + officeId = 2L, + officeName = "Office", + type = type, + date = listOf(2023, 7, 8), + currency = currency, + amount = 10.0, + submittedOnDate = listOf(2023, 7, 9), + reversed = false + ) + val transactions: Page = + Page(totalFilteredRecords = 1, pageItems = listOf(transaction)) + `when`(recentTransactionRepositoryImp.recentTransactions(offset, limit)) + .thenReturn(Observable.just(transactions)) + + viewModel.loadRecentTransactions(loadmore = false, offset) + + verify(recentTransactionUiStateObserver).onChanged(RecentTransactionUiState.Loading) + Assert.assertEquals( + transactions.pageItems.let { RecentTransactionUiState.RecentTransactions(it) }, + viewModel.recentTransactionUiState.value + ) + } + + @Test + fun loadRecentTransaction_success_with_empty_transactions() { + val offset = 0 + val limit = 50 + + val transaction = Transaction( + id = 1L, + officeId = 2L, + officeName = "Office", + type = type, + date = listOf(2023, 7, 8), + currency = currency, + amount = 10.0, + submittedOnDate = listOf(2023, 7, 9), + reversed = false + ) + val transactions: Page = + Page(totalFilteredRecords = 0, pageItems = listOf(transaction)) + `when`(recentTransactionRepositoryImp.recentTransactions(offset, limit)) + .thenReturn(Observable.just(transactions)) + + viewModel.loadRecentTransactions(loadmore = false, offset) + + verify(recentTransactionUiStateObserver).onChanged(RecentTransactionUiState.Loading) + Assert.assertEquals( + RecentTransactionUiState.EmptyTransaction, + viewModel.recentTransactionUiState.value + ) + } + + @Test + fun loadRecentTransaction_success_with_load_more_transactions() { + val offset = 0 + val limit = 50 + + val transaction = Transaction( + id = 1L, + officeId = 2L, + officeName = "Office", + type = type, + date = listOf(2023, 7, 8), + currency = currency, + amount = 10.0, + submittedOnDate = listOf(2023, 7, 9), + reversed = false + ) + val transactions: Page = + Page(totalFilteredRecords = 1, pageItems = listOf(transaction)) + `when`(recentTransactionRepositoryImp.recentTransactions(offset, limit)) + .thenReturn(Observable.just(transactions)) + + viewModel.loadRecentTransactions(loadmore = true, offset) + + verify(recentTransactionUiStateObserver).onChanged(RecentTransactionUiState.Loading) + Assert.assertEquals( + transactions.pageItems.let { RecentTransactionUiState.LoadMoreRecentTransactions(it) }, + viewModel.recentTransactionUiState.value + ) + + } + + @Test + fun loadRecentTransaction_unsuccessful() { + val error = Throwable("Recent Transaction error") + `when`(recentTransactionRepositoryImp.recentTransactions(anyInt(), anyInt())).thenReturn( + Observable.error(error) + ) + viewModel.loadRecentTransactions(false, 0) + + Assert.assertEquals( + RecentTransactionUiState.Error(R.string.recent_transactions), + viewModel.recentTransactionUiState.value + ) + } + + @After + fun tearDown() { + viewModel.recentTransactionUiState.removeObserver(recentTransactionUiStateObserver) + } + +} \ No newline at end of file From cd3b0f497d0c2e67e83003ee8255afef3249d188 Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Sun, 9 Jul 2023 18:47:38 +0530 Subject: [PATCH 28/35] feat : updatepassword fragment mvvm migration -> added viewModel and repository -> refactored "RegistrationUiState" to "UiState" so that it could be used across registrationFragment and updatePasscode fragment -> refactored updatePassword fragment's exisiting code, to use more kotlin specific ways. -> shifted client related logic from userAuthRepository to ClientRepository. -> added client repository to update password fragment using hilt, and modified repository module accordingly. --- .../injection/module/RepositoryModule.kt | 8 + .../mobile/repositories/ClientRepository.kt | 6 + .../repositories/ClientRepositoryImp.kt | 19 ++ .../mobile/repositories/UserAuthRepository.kt | 5 + .../repositories/UserAuthRepositoryImp.kt | 16 +- .../ui/fragments/RegistrationFragment.kt | 8 +- .../ui/fragments/UpdatePasswordFragment.kt | 209 +++++++++--------- .../mifos/mobile/utils/RegistrationUiState.kt | 7 - .../java/org/mifos/mobile/utils/UiState.kt | 7 + .../viewModels/RegistrationViewModel.kt | 12 +- .../viewModels/UpdatePasswordViewModel.kt | 62 ++++++ .../viewModels/RegistrationViewModelTest.kt | 14 +- 12 files changed, 245 insertions(+), 128 deletions(-) create mode 100644 app/src/main/java/org/mifos/mobile/repositories/ClientRepository.kt create mode 100644 app/src/main/java/org/mifos/mobile/repositories/ClientRepositoryImp.kt delete mode 100644 app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt create mode 100644 app/src/main/java/org/mifos/mobile/utils/UiState.kt create mode 100644 app/src/main/java/org/mifos/mobile/viewModels/UpdatePasswordViewModel.kt diff --git a/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt index 2063047cc..dff1aadb2 100644 --- a/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt +++ b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt @@ -5,6 +5,9 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import org.mifos.mobile.api.DataManager +import org.mifos.mobile.api.local.PreferencesHelper +import org.mifos.mobile.repositories.ClientRepository +import org.mifos.mobile.repositories.ClientRepositoryImp import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.repositories.UserAuthRepositoryImp @@ -16,4 +19,9 @@ class RepositoryModule { fun providesUserAuthRepository(dataManager: DataManager): UserAuthRepository { return UserAuthRepositoryImp(dataManager) } + + @Provides + fun providesClientRepository(preferencesHelper: PreferencesHelper): ClientRepository { + return ClientRepositoryImp(preferencesHelper) + } } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/ClientRepository.kt b/app/src/main/java/org/mifos/mobile/repositories/ClientRepository.kt new file mode 100644 index 000000000..4a8b2e707 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/repositories/ClientRepository.kt @@ -0,0 +1,6 @@ +package org.mifos.mobile.repositories + +interface ClientRepository { + + fun updateAuthenticationToken(password: String) +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/ClientRepositoryImp.kt b/app/src/main/java/org/mifos/mobile/repositories/ClientRepositoryImp.kt new file mode 100644 index 000000000..12931d1a6 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/repositories/ClientRepositoryImp.kt @@ -0,0 +1,19 @@ +package org.mifos.mobile.repositories + +import okhttp3.Credentials +import org.mifos.mobile.api.BaseApiManager +import org.mifos.mobile.api.local.PreferencesHelper +import javax.inject.Inject + +class ClientRepositoryImp @Inject constructor(private val preferencesHelper: PreferencesHelper) : ClientRepository { + + override fun updateAuthenticationToken(password: String) { + val authenticationToken = Credentials.basic(preferencesHelper.userName!!, password) + preferencesHelper.saveToken(authenticationToken) + BaseApiManager.createService( + preferencesHelper.baseUrl, + preferencesHelper.tenant, + preferencesHelper.token, + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt index 145c251ef..db996f66c 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepository.kt @@ -15,4 +15,9 @@ interface UserAuthRepository { password: String?, username: String? ): Observable? + + fun updateAccountPassword( + newPassword: String, confirmPassword: String + ): Observable? + } diff --git a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt index 27f45872d..1ec16eb3e 100644 --- a/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt +++ b/app/src/main/java/org/mifos/mobile/repositories/UserAuthRepositoryImp.kt @@ -3,11 +3,11 @@ package org.mifos.mobile.repositories import io.reactivex.Observable import okhttp3.ResponseBody import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.UpdatePasswordPayload import org.mifos.mobile.models.register.RegisterPayload import javax.inject.Inject -class UserAuthRepositoryImp @Inject constructor(private val dataManager: DataManager) : - UserAuthRepository { +class UserAuthRepositoryImp @Inject constructor(private val dataManager: DataManager) : UserAuthRepository { override fun registerUser( accountNumber: String?, @@ -31,4 +31,16 @@ class UserAuthRepositoryImp @Inject constructor(private val dataManager: DataMan } return dataManager.registerUser(registerPayload) } + + override fun updateAccountPassword( + newPassword: String, confirmPassword: String + ): Observable? { + val payload = UpdatePasswordPayload().apply { + this.password = newPassword + this.repeatPassword = confirmPassword + } + + return dataManager.updateAccountPassword(payload) + } + } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt index 889047a32..76b318e27 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt @@ -19,7 +19,7 @@ import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.utils.MFErrorParser import org.mifos.mobile.utils.Network import org.mifos.mobile.utils.PasswordStrength -import org.mifos.mobile.utils.RegistrationUiState +import org.mifos.mobile.utils.UiState import org.mifos.mobile.utils.Toaster import org.mifos.mobile.viewModels.RegistrationViewModel @@ -91,14 +91,14 @@ class RegistrationFragment : BaseFragment() { viewModel.registrationUiState.observe(viewLifecycleOwner) { state -> when (state) { - RegistrationUiState.Loading -> showProgress() + UiState.Loading -> showProgress() - RegistrationUiState.RegistrationSuccessful -> { + UiState.Success -> { hideProgress() showRegisteredSuccessfully() } - is RegistrationUiState.ErrorOnRegistration -> { + is UiState.Error -> { hideProgress() showError(MFErrorParser.errorMessage(state.exception)) } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt index 5ab5f2152..3443d60a7 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt @@ -8,40 +8,27 @@ import android.view.View import android.view.View.OnFocusChangeListener import android.view.ViewGroup import android.widget.Toast +import androidx.lifecycle.ViewModelProvider import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R -import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.databinding.FragmentUpdatePasswordBinding -import org.mifos.mobile.models.UpdatePasswordPayload -import org.mifos.mobile.presenters.UpdatePasswordPresenter import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.fragments.base.BaseFragment -import org.mifos.mobile.ui.views.UpdatePasswordView +import org.mifos.mobile.utils.MFErrorParser import org.mifos.mobile.utils.Network import org.mifos.mobile.utils.Toaster -import javax.inject.Inject +import org.mifos.mobile.utils.UiState +import org.mifos.mobile.viewModels.UpdatePasswordViewModel /* * Created by saksham on 13/July/2018 */ @AndroidEntryPoint -class UpdatePasswordFragment : - BaseFragment(), - UpdatePasswordView, - TextWatcher, - OnFocusChangeListener { +class UpdatePasswordFragment : BaseFragment(), TextWatcher, OnFocusChangeListener { private var _binding: FragmentUpdatePasswordBinding? = null private val binding get() = _binding!! - - @JvmField - @Inject - var presenter: UpdatePasswordPresenter? = null - - @JvmField - @Inject - var preferencesHelper: PreferencesHelper? = null - private var payload: UpdatePasswordPayload? = null + private lateinit var viewModel: UpdatePasswordViewModel private var isFocusLostNewPassword = false private var isFocusLostConfirmPassword = false @@ -52,7 +39,7 @@ class UpdatePasswordFragment : ): View { _binding = FragmentUpdatePasswordBinding.inflate(inflater, container, false) setToolbarTitle(getString(R.string.change_password)) - presenter?.attachView(this) + viewModel = ViewModelProvider(this)[UpdatePasswordViewModel::class.java] binding.tilNewPassword.editText?.addTextChangedListener(this) binding.tilConfirmNewPassword.editText?.addTextChangedListener(this) binding.tilNewPassword.editText?.onFocusChangeListener = this @@ -65,50 +52,115 @@ class UpdatePasswordFragment : binding.btnUpdatePassword.setOnClickListener { updatePassword() } + + viewModel.updatePasswordUiState.observe(viewLifecycleOwner) { state -> + when (state) { + UiState.Loading -> showProgress() + UiState.Success -> { + hideProgress() + showPasswordUpdatedSuccessfully() + } + + is UiState.Error -> { + hideProgress() + showError(MFErrorParser.errorMessage(state.exception)) + } + } + } } - fun updatePassword() { - if (isFieldsCompleted) { - presenter?.updateAccountPassword(updatePasswordPayload) + private fun updatePassword() { + val newPassword = binding.tilNewPassword.editText?.text.toString().trim() + val confirmPassword = binding.tilConfirmNewPassword.editText?.text.toString().trim() + + if (areFieldsValidated(newPassword, confirmPassword)) { + viewModel.updateAccountPassword(newPassword, confirmPassword) } } - private val isFieldsCompleted: Boolean - get() { - var rv = true - val newPassword = binding.tilNewPassword.editText?.text.toString().trim { it <= ' ' } - val repeatPassword = - binding.tilConfirmNewPassword.editText?.text.toString().trim { it <= ' ' } - if (!checkNewPasswordFieldsComplete()) { - rv = false - } - if (!checkConfirmPasswordFieldsComplete()) { - rv = false - } - if (newPassword != repeatPassword) { + private fun areFieldsValidated(newPassword: String, confirmPassword: String): Boolean { + return when { + !isNewPasswordValidated() -> false + !isConfirmPasswordValidated() -> false + (!viewModel.validatePasswordMatch(newPassword, confirmPassword)) -> { Toaster.show(binding.root, getString(R.string.error_password_not_match)) - rv = false + false + } + + else -> true + } + } + + private fun isNewPasswordValidated(): Boolean { + with(binding) { + val newPassword = tilNewPassword.editText?.text.toString() + isFocusLostNewPassword = true + return when { + viewModel.isInputFieldEmpty(newPassword) -> { + tilNewPassword.error = getString( + R.string.error_validation_blank, + getString(R.string.new_password), + ) + false + } + + viewModel.isInputLengthInadequate(newPassword) -> { + tilNewPassword.error = getString( + R.string.error_validation_minimum_chars, + getString(R.string.new_password), + resources.getInteger(R.integer.password_minimum_length), + ) + false + } + + else -> { + tilNewPassword.isErrorEnabled = false + return true + } } - return rv } - private val updatePasswordPayload: UpdatePasswordPayload? - get() { - payload = UpdatePasswordPayload() - payload?.password = binding.tilNewPassword.editText?.text.toString().trim { it <= ' ' } - payload?.repeatPassword = - binding.tilConfirmNewPassword.editText?.text.toString().trim { it <= ' ' } - return payload + } + + private fun isConfirmPasswordValidated(): Boolean { + with(binding) { + val confirmPassword = tilConfirmNewPassword.editText?.text.toString() + isFocusLostConfirmPassword = true + return when { + viewModel.isInputFieldEmpty(confirmPassword) -> { + tilConfirmNewPassword.error = getString( + R.string.error_validation_blank, + getString(R.string.confirm_password), + ) + false + } + + viewModel.isInputLengthInadequate(confirmPassword) -> { + tilConfirmNewPassword.error = getString( + R.string.error_validation_minimum_chars, + getString(R.string.confirm_password), + resources.getInteger(R.integer.password_minimum_length), + ) + return false + } + + else -> { + tilConfirmNewPassword.isErrorEnabled = false + return true + } + } } - override fun showError(message: String?) { - var message = message + } + + fun showError(message: String?) { + var errorMessage = message if (!Network.isConnected(activity)) { - message = getString(R.string.no_internet_connection) + errorMessage = getString(R.string.no_internet_connection) } - Toaster.show(binding.root, message) + Toaster.show(binding.root, errorMessage) } - override fun showPasswordUpdatedSuccessfully() { + private fun showPasswordUpdatedSuccessfully() { Toast.makeText( context, getString( @@ -125,86 +177,41 @@ class UpdatePasswordFragment : ) } - override fun showProgress() { + fun showProgress() { showMifosProgressDialog(getString(R.string.progress_message_loading)) } - override fun hideProgress() { + fun hideProgress() { hideMifosProgressDialog() } override fun onDestroyView() { super.onDestroyView() - presenter?.detachView() _binding = null } override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { if (binding.tilNewPassword.editText?.hasFocus() == true && isFocusLostNewPassword) { - checkNewPasswordFieldsComplete() + isNewPasswordValidated() } if (binding.tilConfirmNewPassword.editText?.hasFocus() == true && isFocusLostConfirmPassword) { - checkConfirmPasswordFieldsComplete() + isConfirmPasswordValidated() } } override fun afterTextChanged(s: Editable) {} override fun onFocusChange(v: View, hasFocus: Boolean) { if (v.id == R.id.et_new_password && !isFocusLostNewPassword && !hasFocus) { - checkNewPasswordFieldsComplete() + isNewPasswordValidated() isFocusLostNewPassword = true } if (v.id == R.id.et_confirm_password && !isFocusLostConfirmPassword && !hasFocus) { - checkConfirmPasswordFieldsComplete() + isConfirmPasswordValidated() isFocusLostConfirmPassword = true } } - private fun checkNewPasswordFieldsComplete(): Boolean { - val newPassword = binding.tilNewPassword.editText?.text.toString() - isFocusLostNewPassword = true - if (newPassword.isEmpty()) { - binding.tilNewPassword.error = getString( - R.string.error_validation_blank, - getString(R.string.new_password), - ) - return false - } - if (newPassword.length < 6) { - binding.tilNewPassword.error = getString( - R.string.error_validation_minimum_chars, - getString(R.string.new_password), - resources.getInteger(R.integer.password_minimum_length), - ) - return false - } - binding.tilNewPassword.isErrorEnabled = false - return true - } - - private fun checkConfirmPasswordFieldsComplete(): Boolean { - val confirmPassword = binding.tilConfirmNewPassword.editText?.text.toString() - isFocusLostConfirmPassword = true - if (confirmPassword.isEmpty()) { - binding.tilConfirmNewPassword.error = getString( - R.string.error_validation_blank, - getString(R.string.confirm_password), - ) - return false - } - if (confirmPassword.length < 6) { - binding.tilConfirmNewPassword.error = getString( - R.string.error_validation_minimum_chars, - getString(R.string.confirm_password), - resources.getInteger(R.integer.password_minimum_length), - ) - return false - } - binding.tilConfirmNewPassword.isErrorEnabled = false - return true - } - companion object { @JvmStatic fun newInstance(): UpdatePasswordFragment { diff --git a/app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt b/app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt deleted file mode 100644 index a380f5222..000000000 --- a/app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.mifos.mobile.utils - -sealed class RegistrationUiState { - data class ErrorOnRegistration(val exception: Throwable) : RegistrationUiState() - object RegistrationSuccessful : RegistrationUiState() - object Loading : RegistrationUiState() -} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/utils/UiState.kt b/app/src/main/java/org/mifos/mobile/utils/UiState.kt new file mode 100644 index 000000000..5180a9059 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/utils/UiState.kt @@ -0,0 +1,7 @@ +package org.mifos.mobile.utils + +sealed class UiState { + data class Error(val exception: Throwable) : UiState() + object Success : UiState() + object Loading : UiState() +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt index f773d8d9f..2420a4c97 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt @@ -11,7 +11,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.mifos.mobile.repositories.UserAuthRepository -import org.mifos.mobile.utils.RegistrationUiState +import org.mifos.mobile.utils.UiState import javax.inject.Inject @HiltViewModel @@ -19,8 +19,8 @@ class RegistrationViewModel @Inject constructor(private val userAuthRepositoryIm ViewModel() { private val compositeDisposables: CompositeDisposable = CompositeDisposable() - private val _registrationUiState = MutableLiveData() - val registrationUiState: LiveData get() = _registrationUiState + private val _registrationUiState = MutableLiveData() + val registrationUiState: LiveData get() = _registrationUiState fun isInputFieldBlank(fieldText: String): Boolean { return fieldText.trim().isEmpty() @@ -52,7 +52,7 @@ class RegistrationViewModel @Inject constructor(private val userAuthRepositoryIm password: String, username: String ) { - _registrationUiState.value = RegistrationUiState.Loading + _registrationUiState.value = UiState.Loading userAuthRepositoryImp.registerUser( accountNumber, authenticationMode, @@ -66,11 +66,11 @@ class RegistrationViewModel @Inject constructor(private val userAuthRepositoryIm ?.subscribeWith(object : DisposableObserver() { override fun onComplete() {} override fun onError(e: Throwable) { - _registrationUiState.value = RegistrationUiState.ErrorOnRegistration(e) + _registrationUiState.value = UiState.Error(e) } override fun onNext(responseBody: ResponseBody) { - _registrationUiState.value = RegistrationUiState.RegistrationSuccessful + _registrationUiState.value = UiState.Success } })?.let { compositeDisposables.add(it) } } diff --git a/app/src/main/java/org/mifos/mobile/viewModels/UpdatePasswordViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/UpdatePasswordViewModel.kt new file mode 100644 index 000000000..747485278 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/viewModels/UpdatePasswordViewModel.kt @@ -0,0 +1,62 @@ +package org.mifos.mobile.viewModels + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.observers.DisposableObserver +import io.reactivex.schedulers.Schedulers +import okhttp3.ResponseBody +import org.mifos.mobile.repositories.ClientRepository +import org.mifos.mobile.repositories.UserAuthRepository +import org.mifos.mobile.utils.UiState +import javax.inject.Inject + +@HiltViewModel +class UpdatePasswordViewModel @Inject constructor( + private val userAuthRepositoryImp: UserAuthRepository, + private val clientRepositoryImp: ClientRepository +) : ViewModel() { + + private val compositeDisposable = CompositeDisposable() + private val _updatePasswordUiState = MutableLiveData() + val updatePasswordUiState: LiveData get() = _updatePasswordUiState + fun isInputFieldEmpty(fieldText: String): Boolean { + return fieldText.isEmpty() + } + + fun isInputLengthInadequate(fieldText: String): Boolean { + return fieldText.length < 6 + } + + fun validatePasswordMatch(newPassword: String, confirmPassword: String): Boolean { + return newPassword == confirmPassword + } + + fun updateAccountPassword(newPassword: String, confirmPassword: String) { + _updatePasswordUiState.value = UiState.Loading + userAuthRepositoryImp.updateAccountPassword(newPassword, confirmPassword) + ?.subscribeOn(Schedulers.io()) + ?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribeWith(object : DisposableObserver() { + override fun onNext(responseBody: ResponseBody) { + _updatePasswordUiState.value = UiState.Success + clientRepositoryImp.updateAuthenticationToken(newPassword) + } + + override fun onError(e: Throwable) { + _updatePasswordUiState.value = UiState.Error(e) + } + + override fun onComplete() {} + })?.let { compositeDisposable.add(it) } + } + + + override fun onCleared() { + super.onCleared() + compositeDisposable.clear() + } +} \ No newline at end of file diff --git a/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt index 63d0f6d64..9c3160bf4 100644 --- a/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt +++ b/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt @@ -12,7 +12,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mifos.mobile.repositories.UserAuthRepositoryImp import org.mifos.mobile.util.RxSchedulersOverrideRule -import org.mifos.mobile.utils.RegistrationUiState +import org.mifos.mobile.utils.UiState import org.mockito.Mock import org.mockito.Mockito import org.mockito.MockitoAnnotations @@ -33,7 +33,7 @@ class RegistrationViewModelTest { lateinit var userAuthRepositoryImp: UserAuthRepositoryImp @Mock - lateinit var registrationUiStateObserver: Observer + lateinit var registrationUiStateObserver: Observer private lateinit var registrationViewModel: RegistrationViewModel @@ -127,9 +127,8 @@ class RegistrationViewModelTest { "userName" ) - Mockito.verify(registrationUiStateObserver).onChanged(RegistrationUiState.Loading) - Mockito.verify(registrationUiStateObserver) - .onChanged(RegistrationUiState.RegistrationSuccessful) + Mockito.verify(registrationUiStateObserver).onChanged(UiState.Loading) + Mockito.verify(registrationUiStateObserver).onChanged(UiState.Success) Mockito.verifyNoMoreInteractions(registrationUiStateObserver) } @@ -160,9 +159,8 @@ class RegistrationViewModelTest { "username" ) - Mockito.verify(registrationUiStateObserver).onChanged(RegistrationUiState.Loading) - Mockito.verify(registrationUiStateObserver) - .onChanged(RegistrationUiState.ErrorOnRegistration(error)) + Mockito.verify(registrationUiStateObserver).onChanged(UiState.Loading) + Mockito.verify(registrationUiStateObserver).onChanged(UiState.Error(error)) Mockito.verifyNoMoreInteractions(registrationUiStateObserver) } From 1edb472ca38398b12b5412979456061b88d47b66 Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Tue, 11 Jul 2023 23:43:24 +0530 Subject: [PATCH 29/35] feat : updatePassword mvvm migration -> added unit tests for updatePasswordViewModel --- .../viewModels/UpdatePasswordViewModelTest.kt | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 app/src/test/java/org/mifos/mobile/viewModels/UpdatePasswordViewModelTest.kt diff --git a/app/src/test/java/org/mifos/mobile/viewModels/UpdatePasswordViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/UpdatePasswordViewModelTest.kt new file mode 100644 index 000000000..e31fbe326 --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/viewModels/UpdatePasswordViewModelTest.kt @@ -0,0 +1,122 @@ +package org.mifos.mobile.viewModels + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import androidx.lifecycle.Observer +import io.reactivex.Observable +import okhttp3.ResponseBody + +import org.junit.After +import org.junit.Assert +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mifos.mobile.repositories.ClientRepository +import org.mifos.mobile.repositories.UserAuthRepository +import org.mifos.mobile.util.RxSchedulersOverrideRule +import org.mifos.mobile.utils.UiState +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner +import kotlin.RuntimeException + +@RunWith(MockitoJUnitRunner::class) +class UpdatePasswordViewModelTest { + + @JvmField + @Rule + val mOverrideSchedulersRule = RxSchedulersOverrideRule() + + @get:Rule + val rule = InstantTaskExecutorRule() + + @Mock + lateinit var userAuthRepositoryImp: UserAuthRepository + + @Mock + lateinit var clientRepositoryImp: ClientRepository + + @Mock + private lateinit var updatePasswordUiStateObserver: Observer + + private lateinit var updatePasswordViewModel: UpdatePasswordViewModel + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + updatePasswordViewModel = + UpdatePasswordViewModel(userAuthRepositoryImp, clientRepositoryImp) + updatePasswordViewModel.updatePasswordUiState.observeForever(updatePasswordUiStateObserver) + } + + @Test + fun testIsInputFieldEmpty_WithEmptyStringInput_ReturnsTrue() { + val result = updatePasswordViewModel.isInputFieldEmpty("") + Assert.assertTrue(result) + } + + @Test + fun testIsInputFieldEmpty_WithNonEmptyStringInput_ReturnsFalse() { + val result = updatePasswordViewModel.isInputFieldEmpty("nonEmptyStringInput") + Assert.assertFalse(result) + } + + @Test + fun testIsInputLengthInadequate_WithAdequateLengthInput_ReturnsFalse() { + val result = updatePasswordViewModel.isInputLengthInadequate("Password123") + Assert.assertFalse(result) + } + + @Test + fun testIsInputLengthInadequate_WithInadequateLengthInput_ReturnsTrue() { + val result = updatePasswordViewModel.isInputLengthInadequate("") + Assert.assertTrue(result) + } + + @Test + fun testValidatePasswordMatch_WithSamePasswords_ReturnsTrue() { + val result = updatePasswordViewModel.validatePasswordMatch("password", "password") + Assert.assertTrue(result) + } + + @Test + fun testValidatePasswordMatch_WithDifferentPasswords_ReturnsFalse() { + val result = updatePasswordViewModel.validatePasswordMatch("password1", "password2") + Assert.assertFalse(result) + } + + @Test + fun testUpdateAccountPassword_SuccessReceivedFromRepository_ReturnsSuccess() { + val responseBody = Mockito.mock(ResponseBody::class.java) + Mockito.`when`( + userAuthRepositoryImp.updateAccountPassword(Mockito.anyString(), Mockito.anyString()) + ).thenReturn(Observable.just(responseBody)) + + updatePasswordViewModel.updateAccountPassword("newPassword", "newPassword") + Mockito.verify(updatePasswordUiStateObserver).onChanged(UiState.Loading) + Mockito.verify(updatePasswordUiStateObserver).onChanged(UiState.Success) + Mockito.verify(clientRepositoryImp).updateAuthenticationToken("newPassword") + Mockito.verifyNoMoreInteractions(updatePasswordUiStateObserver) + } + + @Test + fun testUpdateAccountPassword_ErrorReceivedFromRepository_ReturnsError() { + val error = RuntimeException("fail") + Mockito.`when`( + userAuthRepositoryImp.updateAccountPassword(Mockito.anyString(), Mockito.anyString()) + ).thenReturn(Observable.error(error)) + + updatePasswordViewModel.updateAccountPassword("newPassword", "newPassword") + + Mockito.verify(updatePasswordUiStateObserver).onChanged(UiState.Loading) + Mockito.verify(updatePasswordUiStateObserver).onChanged(UiState.Error(error)) + Mockito.verifyNoMoreInteractions(updatePasswordUiStateObserver) + } + + + @After + fun tearDown() { + updatePasswordViewModel.updatePasswordUiState.removeObserver(updatePasswordUiStateObserver) + } +} \ No newline at end of file From 3b97626fc516fbf5d53c9bf7b31fa7d7dca9c8c4 Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Fri, 14 Jul 2023 13:13:41 +0530 Subject: [PATCH 30/35] feat : updatepassword mvvm migration -> added unit tests for client repository. --- .../repositories/ClientRepositoryImpTest.kt | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt diff --git a/app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt b/app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt new file mode 100644 index 000000000..7ded8c55e --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt @@ -0,0 +1,42 @@ +package org.mifos.mobile.repositories + +import okhttp3.Credentials +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mifos.mobile.api.BaseURL +import org.mifos.mobile.api.local.PreferencesHelper +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner + +@RunWith(MockitoJUnitRunner::class) +class ClientRepositoryImpTest { + + @Mock + lateinit var preferencesHelper: PreferencesHelper + + private lateinit var clientRepositoryImp: ClientRepository + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + clientRepositoryImp = ClientRepositoryImp(preferencesHelper) + } + + @Test + fun test() { + val mockPassword = "testPassword" + val mockUsername = "testUsername" + Mockito.`when`(preferencesHelper.userName).thenReturn(mockUsername) + + Mockito.`when`(preferencesHelper.baseUrl) + .thenReturn(BaseURL.PROTOCOL_HTTPS + BaseURL.API_ENDPOINT) + + clientRepositoryImp.updateAuthenticationToken(mockPassword) + val authenticationToken = Credentials.basic(preferencesHelper.userName!!, mockPassword) + + Mockito.verify(preferencesHelper).saveToken(authenticationToken) + } +} \ No newline at end of file From b2997f3e0262e37100083ba717746651103a29f9 Mon Sep 17 00:00:00 2001 From: Pratyush Singh Date: Sat, 15 Jul 2023 01:08:31 +0530 Subject: [PATCH 31/35] feat: migrated loan related presenter to mvvm --- .../injection/module/RepositoryModule.kt | 7 ++ .../mobile/repositories/LoanRepository.kt | 26 ++++++ .../mobile/repositories/LoanRepositoryImp.kt | 34 ++++++++ .../LoanAccountTransactionFragment.kt | 50 ++++++++---- .../fragments/LoanAccountWithdrawFragment.kt | 41 ++++++---- .../fragments/LoanAccountsDetailFragment.kt | 48 ++++++----- .../ui/fragments/LoanApplicationFragment.kt | 72 ++++++++++------- .../LoanRepaymentScheduleFragment.kt | 49 ++++++++---- .../org/mifos/mobile/utils/LoanUiState.kt | 16 ++++ .../LoanAccountTransactionViewModel.kt | 61 ++++++++++++++ .../LoanAccountWithdrawViewModel.kt | 48 +++++++++++ .../viewModels/LoanAccountsDetailViewModel.kt | 55 +++++++++++++ .../viewModels/LoanApplicationViewModel.kt | 79 +++++++++++++++++++ .../LoanRepaymentScheduleViewModel.kt | 61 ++++++++++++++ 14 files changed, 554 insertions(+), 93 deletions(-) create mode 100644 app/src/main/java/org/mifos/mobile/repositories/LoanRepository.kt create mode 100644 app/src/main/java/org/mifos/mobile/repositories/LoanRepositoryImp.kt create mode 100644 app/src/main/java/org/mifos/mobile/utils/LoanUiState.kt create mode 100644 app/src/main/java/org/mifos/mobile/viewModels/LoanAccountTransactionViewModel.kt create mode 100644 app/src/main/java/org/mifos/mobile/viewModels/LoanAccountWithdrawViewModel.kt create mode 100644 app/src/main/java/org/mifos/mobile/viewModels/LoanAccountsDetailViewModel.kt create mode 100644 app/src/main/java/org/mifos/mobile/viewModels/LoanApplicationViewModel.kt create mode 100644 app/src/main/java/org/mifos/mobile/viewModels/LoanRepaymentScheduleViewModel.kt diff --git a/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt index 2063047cc..45ec9aa07 100644 --- a/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt +++ b/app/src/main/java/org/mifos/mobile/injection/module/RepositoryModule.kt @@ -5,6 +5,8 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import org.mifos.mobile.api.DataManager +import org.mifos.mobile.repositories.LoanRepository +import org.mifos.mobile.repositories.LoanRepositoryImp import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.repositories.UserAuthRepositoryImp @@ -16,4 +18,9 @@ class RepositoryModule { fun providesUserAuthRepository(dataManager: DataManager): UserAuthRepository { return UserAuthRepositoryImp(dataManager) } + + @Provides + fun providesLoanRepository(dataManager: DataManager): LoanRepository { + return LoanRepositoryImp(dataManager) + } } \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/LoanRepository.kt b/app/src/main/java/org/mifos/mobile/repositories/LoanRepository.kt new file mode 100644 index 000000000..a56dafa14 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/repositories/LoanRepository.kt @@ -0,0 +1,26 @@ +package org.mifos.mobile.repositories + +import io.reactivex.Observable +import okhttp3.ResponseBody +import org.mifos.mobile.models.accounts.loan.LoanWithAssociations +import org.mifos.mobile.models.accounts.loan.LoanWithdraw +import org.mifos.mobile.models.templates.loans.LoanTemplate + +interface LoanRepository { + + fun getLoanWithAssociations( + associationType: String?, + loanId: Long? + ): Observable? + + fun withdrawLoanAccount( + loanId: Long?, + loanWithdraw: LoanWithdraw?, + ): Observable? + + fun template(): Observable? + + fun getLoanTemplateByProduct( + productId: Int? + ): Observable? +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/repositories/LoanRepositoryImp.kt b/app/src/main/java/org/mifos/mobile/repositories/LoanRepositoryImp.kt new file mode 100644 index 000000000..24247da37 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/repositories/LoanRepositoryImp.kt @@ -0,0 +1,34 @@ +package org.mifos.mobile.repositories + +import io.reactivex.Observable +import okhttp3.ResponseBody +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.accounts.loan.LoanWithAssociations +import org.mifos.mobile.models.accounts.loan.LoanWithdraw +import org.mifos.mobile.models.templates.loans.LoanTemplate +import javax.inject.Inject + +class LoanRepositoryImp @Inject constructor(private val dataManager: DataManager) : LoanRepository { + + override fun getLoanWithAssociations( + associationType: String?, + loanId: Long? + ): Observable? { + return dataManager.getLoanWithAssociations(associationType, loanId) + } + + override fun withdrawLoanAccount( + loanId: Long?, + loanWithdraw: LoanWithdraw? + ): Observable? { + return dataManager.withdrawLoanAccount(loanId, loanWithdraw) + } + + override fun template(): Observable? { + return dataManager.loanTemplate + } + + override fun getLoanTemplateByProduct(productId: Int?): Observable? { + return dataManager.getLoanTemplateByProduct(productId) + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt index 0a53df36b..0b4c3db26 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt @@ -7,6 +7,7 @@ import android.view.View import android.view.ViewGroup import android.widget.TextView import android.widget.Toast +import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler @@ -14,12 +15,12 @@ import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentLoanAccountTransactionsBinding import org.mifos.mobile.models.accounts.loan.LoanWithAssociations -import org.mifos.mobile.presenters.LoanAccountsTransactionPresenter import org.mifos.mobile.ui.adapters.RecentTransactionListAdapter import org.mifos.mobile.ui.fragments.base.BaseFragment -import org.mifos.mobile.ui.views.LoanAccountsTransactionView import org.mifos.mobile.utils.Constants +import org.mifos.mobile.utils.LoanUiState import org.mifos.mobile.utils.Network +import org.mifos.mobile.viewModels.LoanAccountTransactionViewModel import javax.inject.Inject /* @@ -29,7 +30,7 @@ import javax.inject.Inject * Created by dilpreet on 4/3/17. */ @AndroidEntryPoint -class LoanAccountTransactionFragment : BaseFragment(), LoanAccountsTransactionView { +class LoanAccountTransactionFragment : BaseFragment() { private var _binding: FragmentLoanAccountTransactionsBinding? = null private val binding get() = _binding!! @@ -37,9 +38,8 @@ class LoanAccountTransactionFragment : BaseFragment(), LoanAccountsTransactionVi @Inject var transactionsListAdapter: RecentTransactionListAdapter? = null - @JvmField - @Inject - var loanAccountsTransactionPresenter: LoanAccountsTransactionPresenter? = null + lateinit var viewModel: LoanAccountTransactionViewModel + private var loanId: Long? = 0 private var loanWithAssociations: LoanWithAssociations? = null private var sweetUIErrorHandler: SweetUIErrorHandler? = null @@ -56,13 +56,13 @@ class LoanAccountTransactionFragment : BaseFragment(), LoanAccountsTransactionVi savedInstanceState: Bundle?, ): View { _binding = FragmentLoanAccountTransactionsBinding.inflate(inflater, container, false) + viewModel = ViewModelProvider(this)[LoanAccountTransactionViewModel::class.java] val rootView = binding.root setToolbarTitle(getString(R.string.transactions)) - loanAccountsTransactionPresenter?.attachView(this) sweetUIErrorHandler = SweetUIErrorHandler(context, rootView) showUserInterface() if (savedInstanceState == null) { - loanAccountsTransactionPresenter?.loadLoanAccountDetails(loanId) + viewModel.loadLoanAccountDetails(loanId) } return rootView } @@ -82,7 +82,7 @@ class LoanAccountTransactionFragment : BaseFragment(), LoanAccountsTransactionVi /** * Initialized [RecyclerView] `rvLoanTransactions` */ - override fun showUserInterface() { + fun showUserInterface() { val layoutManager = LinearLayoutManager(activity) layoutManager.orientation = LinearLayoutManager.VERTICAL with(binding) { @@ -98,7 +98,7 @@ class LoanAccountTransactionFragment : BaseFragment(), LoanAccountsTransactionVi * * @param loanWithAssociations object containing details about a Loan Account with Associations */ - override fun showLoanTransactions(loanWithAssociations: LoanWithAssociations?) { + fun showLoanTransactions(loanWithAssociations: LoanWithAssociations?) { this.loanWithAssociations = loanWithAssociations binding.llLoanAccountTrans.visibility = View.VISIBLE binding.tvLoanProductName.text = loanWithAssociations?.loanProductName @@ -108,7 +108,7 @@ class LoanAccountTransactionFragment : BaseFragment(), LoanAccountsTransactionVi /** * Sets a [TextView] with a msg if Transactions list is empty */ - override fun showEmptyTransactions(loanWithAssociations: LoanWithAssociations?) { + fun showEmptyTransactions(loanWithAssociations: LoanWithAssociations?) { sweetUIErrorHandler?.showSweetEmptyUI( getString(R.string.transactions), R.drawable.ic_compare_arrows_black_24dp, @@ -122,7 +122,7 @@ class LoanAccountTransactionFragment : BaseFragment(), LoanAccountsTransactionVi * * @param message Error message that tells the user about the problem. */ - override fun showErrorFetchingLoanAccountsDetail(message: String?) { + fun showErrorFetchingLoanAccountsDetail(message: String?) { with(binding) { if (!Network.isConnected(activity)) { sweetUIErrorHandler?.showSweetNoInternetUI( @@ -142,6 +142,25 @@ class LoanAccountTransactionFragment : BaseFragment(), LoanAccountsTransactionVi override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + viewModel.loanUiState.observe(viewLifecycleOwner) { + when (it) { + is LoanUiState.Loading -> showProgress() + is LoanUiState.ShowError -> { + hideProgress() + showErrorFetchingLoanAccountsDetail(getString(it.message)) + } + is LoanUiState.ShowLoan -> { + hideProgress() + showLoanTransactions(it.loanWithAssociations) + } + is LoanUiState.ShowEmpty -> { + hideProgress() + showEmptyTransactions(it.loanWithAssociations) + } + } + } + binding.layoutError.btnTryAgain.setOnClickListener { retryClicked() } @@ -153,7 +172,7 @@ class LoanAccountTransactionFragment : BaseFragment(), LoanAccountsTransactionVi binding.rvLoanTransactions, binding.layoutError.root, ) - loanAccountsTransactionPresenter?.loadLoanAccountDetails(loanId) + viewModel.loadLoanAccountDetails(loanId) } else { Toast.makeText( context, @@ -163,18 +182,17 @@ class LoanAccountTransactionFragment : BaseFragment(), LoanAccountsTransactionVi } } - override fun showProgress() { + fun showProgress() { showProgressBar() } - override fun hideProgress() { + fun hideProgress() { hideProgressBar() } override fun onDestroyView() { super.onDestroyView() hideProgressBar() - loanAccountsTransactionPresenter?.detachView() _binding = null } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt index 93ba7b2f7..54e4abdbf 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt @@ -4,31 +4,30 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.lifecycle.ViewModelProvider import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentLoanWithdrawBinding import org.mifos.mobile.models.accounts.loan.LoanWithAssociations import org.mifos.mobile.models.accounts.loan.LoanWithdraw -import org.mifos.mobile.presenters.LoanAccountWithdrawPresenter import org.mifos.mobile.ui.fragments.base.BaseFragment -import org.mifos.mobile.ui.views.LoanAccountWithdrawView import org.mifos.mobile.utils.Constants import org.mifos.mobile.utils.DateHelper +import org.mifos.mobile.utils.LoanUiState import org.mifos.mobile.utils.Toaster -import javax.inject.Inject +import org.mifos.mobile.viewModels.LoanAccountWithdrawViewModel /** * Created by dilpreet on 7/6/17. */ @AndroidEntryPoint -class LoanAccountWithdrawFragment : BaseFragment(), LoanAccountWithdrawView { +class LoanAccountWithdrawFragment : BaseFragment() { private var _binding: FragmentLoanWithdrawBinding? = null private val binding get() = _binding!! - @JvmField - @Inject - var loanAccountWithdrawPresenter: LoanAccountWithdrawPresenter? = null + lateinit var viewModel: LoanAccountWithdrawViewModel + private var loanWithAssociations: LoanWithAssociations? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -43,14 +42,29 @@ class LoanAccountWithdrawFragment : BaseFragment(), LoanAccountWithdrawView { savedInstanceState: Bundle?, ): View { _binding = FragmentLoanWithdrawBinding.inflate(inflater, container, false) + viewModel = ViewModelProvider(this)[LoanAccountWithdrawViewModel::class.java] setToolbarTitle(getString(R.string.withdraw_loan)) showUserInterface() - loanAccountWithdrawPresenter?.attachView(this) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + viewModel.loanUiState.observe(viewLifecycleOwner) { + when (it) { + is LoanUiState.Loading -> showProgress() + is LoanUiState.ShowError -> { + hideProgress() + showLoanAccountWithdrawError(getString(it.message)) + } + is LoanUiState.WithdrawSuccess -> { + hideProgress() + showLoanAccountWithdrawSuccess() + } + } + } + binding.btnWithdrawLoan.setOnClickListener { onLoanWithdraw() } @@ -72,7 +86,7 @@ class LoanAccountWithdrawFragment : BaseFragment(), LoanAccountWithdrawView { loanWithdraw.note = binding.etWithdrawReason.text.toString() loanWithdraw.withdrawnOnDate = DateHelper .getDateAsStringFromLong(System.currentTimeMillis()) - loanAccountWithdrawPresenter?.withdrawLoanAccount( + viewModel.withdrawLoanAccount( loanWithAssociations?.id?.toLong(), loanWithdraw, ) @@ -81,7 +95,7 @@ class LoanAccountWithdrawFragment : BaseFragment(), LoanAccountWithdrawView { /** * Receives A confirmation after successfull withdrawing of Loan Application. */ - override fun showLoanAccountWithdrawSuccess() { + fun showLoanAccountWithdrawSuccess() { Toaster.show(binding.root, R.string.loan_application_withdrawn_successfully) activity?.supportFragmentManager?.popBackStack() } @@ -92,22 +106,21 @@ class LoanAccountWithdrawFragment : BaseFragment(), LoanAccountWithdrawView { * * @param message Error Message displayed */ - override fun showLoanAccountWithdrawError(message: String?) { + fun showLoanAccountWithdrawError(message: String?) { Toaster.show(binding.root, message) } - override fun showProgress() { + fun showProgress() { showProgressBar() } - override fun hideProgress() { + fun hideProgress() { hideProgressBar() } override fun onDestroyView() { super.onDestroyView() hideProgress() - loanAccountWithdrawPresenter?.detachView() _binding = null } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt index 0d9fa83fc..73f850b6a 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt @@ -9,24 +9,20 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import android.widget.Toast +import androidx.lifecycle.ViewModelProvider import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.api.local.PreferencesHelper import org.mifos.mobile.databinding.FragmentLoanAccountDetailsBinding import org.mifos.mobile.models.accounts.loan.LoanWithAssociations -import org.mifos.mobile.presenters.LoanAccountsDetailPresenter import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.enums.AccountType import org.mifos.mobile.ui.enums.ChargeType import org.mifos.mobile.ui.enums.LoanState import org.mifos.mobile.ui.fragments.base.BaseFragment -import org.mifos.mobile.ui.views.LoanAccountsDetailView -import org.mifos.mobile.utils.Constants -import org.mifos.mobile.utils.CurrencyUtil -import org.mifos.mobile.utils.DateHelper -import org.mifos.mobile.utils.Network -import org.mifos.mobile.utils.QrCodeGenerator +import org.mifos.mobile.utils.* +import org.mifos.mobile.viewModels.LoanAccountsDetailViewModel import javax.inject.Inject /* @@ -37,13 +33,11 @@ import javax.inject.Inject * @since 19/08/16 */ @AndroidEntryPoint -class LoanAccountsDetailFragment : BaseFragment(), LoanAccountsDetailView { +class LoanAccountsDetailFragment : BaseFragment() { private var _binding: FragmentLoanAccountDetailsBinding? = null private val binding get() = _binding!! - @JvmField - @Inject - var loanAccountDetailsPresenter: LoanAccountsDetailPresenter? = null + lateinit var viewModel: LoanAccountsDetailViewModel @JvmField @Inject @@ -67,11 +61,11 @@ class LoanAccountsDetailFragment : BaseFragment(), LoanAccountsDetailView { ): View { _binding = FragmentLoanAccountDetailsBinding.inflate(inflater, container, false) val rootView = binding.root + viewModel = ViewModelProvider(this)[LoanAccountsDetailViewModel::class.java] setToolbarTitle(getString(R.string.loan_account_details)) - loanAccountDetailsPresenter?.attachView(this) sweetUIErrorHandler = SweetUIErrorHandler(activity, rootView) if (savedInstanceState == null && this.loanWithAssociations == null) { - loanAccountDetailsPresenter?.loadLoanAccountDetails(loanId) + viewModel.loadLoanAccountDetails(loanId) } else { showLoanAccountsDetail(this.loanWithAssociations) } @@ -96,7 +90,7 @@ class LoanAccountsDetailFragment : BaseFragment(), LoanAccountsDetailView { * * @param loanWithAssociations object containing details of each loan account, */ - override fun showLoanAccountsDetail(loanWithAssociations: LoanWithAssociations?) { + private fun showLoanAccountsDetail(loanWithAssociations: LoanWithAssociations?) { this.loanWithAssociations = loanWithAssociations with(binding) { llAccountDetail.visibility = View.VISIBLE @@ -172,6 +166,21 @@ class LoanAccountsDetailFragment : BaseFragment(), LoanAccountsDetailView { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + viewModel.loanUiState.observe(viewLifecycleOwner) { + when (it) { + is LoanUiState.Loading -> showProgress() + is LoanUiState.ShowError -> { + hideProgress() + showErrorFetchingLoanAccountsDetail(getString(it.message)) + } + is LoanUiState.ShowLoan -> { + hideProgress() + showLoanAccountsDetail(it.loanWithAssociations) + } + } + } + with(binding) { btnMakePayment.setOnClickListener { onMakePaymentClicked() @@ -289,7 +298,7 @@ class LoanAccountsDetailFragment : BaseFragment(), LoanAccountsDetailView { * * @param message Error message that tells the user about the problem. */ - override fun showErrorFetchingLoanAccountsDetail(message: String?) { + fun showErrorFetchingLoanAccountsDetail(message: String?) { if (!Network.isConnected(activity)) { sweetUIErrorHandler?.showSweetNoInternetUI( binding.llAccountDetail, @@ -305,13 +314,13 @@ class LoanAccountsDetailFragment : BaseFragment(), LoanAccountsDetailView { } } - fun retryClicked() { + private fun retryClicked() { if (Network.isConnected(context)) { sweetUIErrorHandler?.hideSweetErrorLayoutUI( binding.llAccountDetail, binding.layoutError.root, ) - loanAccountDetailsPresenter?.loadLoanAccountDetails(loanId) + viewModel.loadLoanAccountDetails(loanId) } else { Toast.makeText( context, @@ -321,18 +330,17 @@ class LoanAccountsDetailFragment : BaseFragment(), LoanAccountsDetailView { } } - override fun showProgress() { + fun showProgress() { showProgressBar() } - override fun hideProgress() { + fun hideProgress() { hideProgressBar() } override fun onDestroyView() { super.onDestroyView() hideProgressBar() - loanAccountDetailsPresenter?.detachView() _binding = null } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt index d84d0ee05..5c087cf83 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt @@ -6,6 +6,7 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.DialogFragment +import androidx.lifecycle.ViewModelProvider import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R import org.mifos.mobile.databinding.FragmentAddLoanApplicationBinding @@ -13,35 +14,26 @@ import org.mifos.mobile.models.accounts.loan.LoanAccount import org.mifos.mobile.models.accounts.loan.LoanWithAssociations import org.mifos.mobile.models.payload.LoansPayload import org.mifos.mobile.models.templates.loans.LoanTemplate -import org.mifos.mobile.presenters.LoanApplicationPresenter import org.mifos.mobile.ui.activities.base.BaseActivity import org.mifos.mobile.ui.enums.LoanState import org.mifos.mobile.ui.fragments.ReviewLoanApplicationFragment.Companion.newInstance import org.mifos.mobile.ui.fragments.base.BaseFragment -import org.mifos.mobile.ui.views.LoanApplicationMvpView -import org.mifos.mobile.utils.Constants -import org.mifos.mobile.utils.DateHelper -import org.mifos.mobile.utils.DatePickerConstrainType -import org.mifos.mobile.utils.Network -import org.mifos.mobile.utils.Toaster -import org.mifos.mobile.utils.getDatePickerDialog -import org.mifos.mobile.utils.getTodayFormatted +import org.mifos.mobile.utils.* +import org.mifos.mobile.viewModels.LoanApplicationViewModel import java.text.SimpleDateFormat import java.time.Instant import java.util.Locale -import javax.inject.Inject /** * Created by Rajan Maurya on 06/03/17. */ @AndroidEntryPoint -class LoanApplicationFragment : BaseFragment(), LoanApplicationMvpView { +class LoanApplicationFragment : BaseFragment() { private var _binding: FragmentAddLoanApplicationBinding? = null private val binding get() = _binding!! - @JvmField - @Inject - var loanApplicationPresenter: LoanApplicationPresenter? = null + lateinit var viewModel: LoanApplicationViewModel + private val listLoanProducts: MutableList = ArrayList() private val listLoanPurpose: MutableList = ArrayList() private var loanTemplate: LoanTemplate? = null @@ -118,7 +110,7 @@ class LoanApplicationFragment : BaseFragment(), LoanApplicationMvpView { savedInstanceState: Bundle?, ): View { _binding = FragmentAddLoanApplicationBinding.inflate(inflater, container, false) - loanApplicationPresenter?.attachView(this) + viewModel = ViewModelProvider(this)[LoanApplicationViewModel::class.java] showUserInterface() if (savedInstanceState == null) { loadLoanTemplate() @@ -148,14 +140,41 @@ class LoanApplicationFragment : BaseFragment(), LoanApplicationMvpView { */ private fun loadLoanTemplate() { if (loanState == LoanState.CREATE) { - loanApplicationPresenter?.loadLoanApplicationTemplate(LoanState.CREATE) + viewModel.loadLoanApplicationTemplate(LoanState.CREATE) } else { - loanApplicationPresenter?.loadLoanApplicationTemplate(LoanState.UPDATE) + viewModel.loadLoanApplicationTemplate(LoanState.UPDATE) } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + viewModel.loanUiState.observe(viewLifecycleOwner) { + when (it) { + is LoanUiState.Loading -> showProgress() + is LoanUiState.ShowError -> { + hideProgress() + showError(getString(it.message)) + } + is LoanUiState.ShowLoanTemplate -> { + hideProgress() + showLoanTemplate(it.template) + } + is LoanUiState.ShowUpdateLoanTemplate -> { + hideProgress() + showUpdateLoanTemplate(it.template) + } + is LoanUiState.ShowLoanTemplateByProduct -> { + hideProgress() + showLoanTemplateByProduct(it.template) + } + is LoanUiState.ShowUpdateLoanTemplateByProduct -> { + hideProgress() + showUpdateLoanTemplateByProduct(it.template) + } + } + } + with(binding) { btnLoanReview.setOnClickListener { onReviewLoanApplication() @@ -333,7 +352,7 @@ class LoanApplicationFragment : BaseFragment(), LoanApplicationMvpView { /** * Initializes the layout */ - override fun showUserInterface() { + fun showUserInterface() { with(binding) { loanProductsField.setSimpleItems(listLoanProducts.toTypedArray()) loanPurposeField.setSimpleItems(listLoanPurpose.toTypedArray()) @@ -341,7 +360,7 @@ class LoanApplicationFragment : BaseFragment(), LoanApplicationMvpView { loanProductsField.setOnItemClickListener { _, _, position, _ -> println("loan_products_field clicked") productId = loanTemplate?.productOptions?.get(position)?.id - loanApplicationPresenter?.loadLoanApplicationTemplateByProduct(productId, loanState) + viewModel.loadLoanApplicationTemplateByProduct(productId, loanState) loanPurposeFieldParent.isEnabled = true } loanPurposeField.setOnItemClickListener { _, _, position, _ -> @@ -363,7 +382,7 @@ class LoanApplicationFragment : BaseFragment(), LoanApplicationMvpView { * * @param loanTemplate Template for Loan Application */ - override fun showLoanTemplate(loanTemplate: LoanTemplate?) { + fun showLoanTemplate(loanTemplate: LoanTemplate?) { this.loanTemplate = loanTemplate if (loanTemplate?.productOptions != null) { for ((_, name) in loanTemplate.productOptions) { @@ -380,7 +399,7 @@ class LoanApplicationFragment : BaseFragment(), LoanApplicationMvpView { * * @param loanTemplate Template for Loan Application */ - override fun showUpdateLoanTemplate(loanTemplate: LoanTemplate?) { + fun showUpdateLoanTemplate(loanTemplate: LoanTemplate?) { this.loanTemplate = loanTemplate if (loanTemplate?.productOptions != null) { for ((_, name) in loanTemplate.productOptions) { @@ -429,7 +448,7 @@ class LoanApplicationFragment : BaseFragment(), LoanApplicationMvpView { * * @param loanTemplate Template for Loan Application */ - override fun showLoanTemplateByProduct(loanTemplate: LoanTemplate?) { + fun showLoanTemplateByProduct(loanTemplate: LoanTemplate?) { this.loanTemplate = loanTemplate with(binding) { tvAccountNumber.text = getString( @@ -462,7 +481,7 @@ class LoanApplicationFragment : BaseFragment(), LoanApplicationMvpView { * * @param loanTemplate Template for Loan Application */ - override fun showUpdateLoanTemplateByProduct(loanTemplate: LoanTemplate?) { + fun showUpdateLoanTemplateByProduct(loanTemplate: LoanTemplate?) { this.loanTemplate = loanTemplate listLoanPurpose.clear() listLoanPurpose.add(activity?.getString(R.string.loan_purpose_not_provided)) @@ -501,7 +520,7 @@ class LoanApplicationFragment : BaseFragment(), LoanApplicationMvpView { * * @param message Error message that tells the user about the problem. */ - override fun showError(message: String?) { + fun showError(message: String?) { with(binding) { if (!Network.isConnected(activity)) { llError.ivStatus.setImageResource(R.drawable.ic_error_black_24dp) @@ -514,12 +533,12 @@ class LoanApplicationFragment : BaseFragment(), LoanApplicationMvpView { } } - override fun showProgress() { + fun showProgress() { binding.llAddLoan.visibility = View.GONE showProgressBar() } - override fun hideProgress() { + fun hideProgress() { binding.llAddLoan.visibility = View.VISIBLE hideProgressBar() } @@ -527,7 +546,6 @@ class LoanApplicationFragment : BaseFragment(), LoanApplicationMvpView { override fun onDestroyView() { super.onDestroyView() hideProgressBar() - loanApplicationPresenter?.detachView() _binding = null } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt index e7ff3ae82..000b25836 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt @@ -7,6 +7,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast +import androidx.lifecycle.ViewModelProvider import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler import dagger.hilt.android.AndroidEntryPoint import org.mifos.mobile.R @@ -16,27 +17,25 @@ import org.mifos.mobile.models.accounts.loan.Periods import org.mifos.mobile.models.accounts.loan.tableview.Cell import org.mifos.mobile.models.accounts.loan.tableview.ColumnHeader import org.mifos.mobile.models.accounts.loan.tableview.RowHeader -import org.mifos.mobile.presenters.LoanRepaymentSchedulePresenter import org.mifos.mobile.ui.adapters.LoanRepaymentScheduleAdapter import org.mifos.mobile.ui.fragments.base.BaseFragment -import org.mifos.mobile.ui.views.LoanRepaymentScheduleMvpView import org.mifos.mobile.utils.Constants import org.mifos.mobile.utils.DateHelper +import org.mifos.mobile.utils.LoanUiState import org.mifos.mobile.utils.Network +import org.mifos.mobile.viewModels.LoanRepaymentScheduleViewModel import javax.inject.Inject /** * Created by Rajan Maurya on 03/03/17. */ @AndroidEntryPoint -class LoanRepaymentScheduleFragment : BaseFragment(), LoanRepaymentScheduleMvpView { +class LoanRepaymentScheduleFragment : BaseFragment() { private var _binding: FragmentLoanRepaymentScheduleBinding? = null private val binding get() = _binding!! - @JvmField - @Inject - var loanRepaymentSchedulePresenter: LoanRepaymentSchedulePresenter? = null + lateinit var viewModel: LoanRepaymentScheduleViewModel @JvmField @Inject @@ -56,17 +55,36 @@ class LoanRepaymentScheduleFragment : BaseFragment(), LoanRepaymentScheduleMvpVi savedInstanceState: Bundle?, ): View { _binding = FragmentLoanRepaymentScheduleBinding.inflate(inflater, container, false) - loanRepaymentSchedulePresenter?.attachView(this) + viewModel = ViewModelProvider(this)[LoanRepaymentScheduleViewModel::class.java] sweetUIErrorHandler = SweetUIErrorHandler(context, binding.root) showUserInterface() if (savedInstanceState == null) { - loanRepaymentSchedulePresenter?.loanLoanWithAssociations(loanId) + viewModel.loanLoanWithAssociations(loanId) } return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + viewModel.loanUiState.observe(viewLifecycleOwner) { + when (it) { + is LoanUiState.Loading -> showProgress() + is LoanUiState.ShowError -> { + hideProgress() + showError(getString(it.message)) + } + is LoanUiState.ShowLoan -> { + hideProgress() + showLoanRepaymentSchedule(it.loanWithAssociations) + } + is LoanUiState.ShowEmpty -> { + hideProgress() + showEmptyRepaymentsSchedule(loanWithAssociations) + } + } + } + binding.layoutError.btnTryAgain.setOnClickListener { retryClicked() } @@ -87,7 +105,7 @@ class LoanRepaymentScheduleFragment : BaseFragment(), LoanRepaymentScheduleMvpVi /** * Initializes the layout */ - override fun showUserInterface() { + fun showUserInterface() { val columnWidth: Double binding.tvRepaymentSchedule.setHasFixedWidth(true) val orientation = resources.configuration.orientation @@ -101,11 +119,11 @@ class LoanRepaymentScheduleFragment : BaseFragment(), LoanRepaymentScheduleMvpVi loanRepaymentScheduleAdapter?.setColumnWidth(columnWidth) } - override fun showProgress() { + fun showProgress() { showProgressBar() } - override fun hideProgress() { + fun hideProgress() { hideProgressBar() } @@ -114,7 +132,7 @@ class LoanRepaymentScheduleFragment : BaseFragment(), LoanRepaymentScheduleMvpVi * * @param loanWithAssociations Contains details about Repayment Schedule */ - override fun showLoanRepaymentSchedule(loanWithAssociations: LoanWithAssociations?) { + fun showLoanRepaymentSchedule(loanWithAssociations: LoanWithAssociations?) { this.loanWithAssociations = loanWithAssociations var currencyRepresentation = loanWithAssociations?.currency?.displaySymbol loanRepaymentScheduleAdapter @@ -151,7 +169,7 @@ class LoanRepaymentScheduleFragment : BaseFragment(), LoanRepaymentScheduleMvpVi * * @param loanWithAssociations Contains details about Repayment Schedule */ - override fun showEmptyRepaymentsSchedule(loanWithAssociations: LoanWithAssociations?) { + fun showEmptyRepaymentsSchedule(loanWithAssociations: LoanWithAssociations?) { binding.tvAccountNumber.text = loanWithAssociations?.accountNo binding.tvDisbursementDate.text = DateHelper.getDateAsString(loanWithAssociations?.timeline?.expectedDisbursementDate) @@ -169,7 +187,7 @@ class LoanRepaymentScheduleFragment : BaseFragment(), LoanRepaymentScheduleMvpVi * * @param message Error message that tells the user about the problem. */ - override fun showError(message: String?) { + fun showError(message: String?) { if (!Network.isConnected(activity)) { sweetUIErrorHandler?.showSweetNoInternetUI( binding.tvRepaymentSchedule, @@ -191,7 +209,7 @@ class LoanRepaymentScheduleFragment : BaseFragment(), LoanRepaymentScheduleMvpVi binding.tvRepaymentSchedule, binding.layoutError.root, ) - loanRepaymentSchedulePresenter?.loanLoanWithAssociations(loanId) + viewModel.loanLoanWithAssociations(loanId) } else { Toast.makeText( context, @@ -204,7 +222,6 @@ class LoanRepaymentScheduleFragment : BaseFragment(), LoanRepaymentScheduleMvpVi override fun onDestroyView() { super.onDestroyView() hideProgressBar() - loanRepaymentSchedulePresenter?.detachView() _binding = null } diff --git a/app/src/main/java/org/mifos/mobile/utils/LoanUiState.kt b/app/src/main/java/org/mifos/mobile/utils/LoanUiState.kt new file mode 100644 index 000000000..76a672c71 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/utils/LoanUiState.kt @@ -0,0 +1,16 @@ +package org.mifos.mobile.utils + +import org.mifos.mobile.models.accounts.loan.LoanWithAssociations +import org.mifos.mobile.models.templates.loans.LoanTemplate + +sealed class LoanUiState { + object Loading : LoanUiState() + object WithdrawSuccess : LoanUiState() + data class ShowError(val message: Int) : LoanUiState() + data class ShowLoan(val loanWithAssociations: LoanWithAssociations) : LoanUiState() + data class ShowEmpty(val loanWithAssociations: LoanWithAssociations) : LoanUiState() + data class ShowLoanTemplate(val template: LoanTemplate) : LoanUiState() + data class ShowUpdateLoanTemplate(val template: LoanTemplate) : LoanUiState() + data class ShowLoanTemplateByProduct(val template: LoanTemplate) : LoanUiState() + data class ShowUpdateLoanTemplateByProduct(val template: LoanTemplate) : LoanUiState() +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/LoanAccountTransactionViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/LoanAccountTransactionViewModel.kt new file mode 100644 index 000000000..9686e4157 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/viewModels/LoanAccountTransactionViewModel.kt @@ -0,0 +1,61 @@ +package org.mifos.mobile.viewModels + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.observers.DisposableObserver +import io.reactivex.schedulers.Schedulers +import org.mifos.mobile.R +import org.mifos.mobile.models.accounts.loan.LoanWithAssociations +import org.mifos.mobile.repositories.LoanRepository +import org.mifos.mobile.utils.Constants +import org.mifos.mobile.utils.LoanUiState +import javax.inject.Inject + +@HiltViewModel +class LoanAccountTransactionViewModel @Inject constructor(private val loanRepositoryImp: LoanRepository) : + ViewModel() { + + private val compositeDisposables: CompositeDisposable = CompositeDisposable() + + private val _loanUiState = MutableLiveData() + val loanUiState: LiveData get() = _loanUiState + + fun loadLoanAccountDetails(loanId: Long?) { + _loanUiState.value = LoanUiState.Loading + loanRepositoryImp.getLoanWithAssociations( + Constants.TRANSACTIONS, + loanId, + )?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribeOn(Schedulers.io()) + ?.subscribeWith(object : DisposableObserver() { + override fun onComplete() {} + override fun onError(e: Throwable) { + _loanUiState.value = + LoanUiState.ShowError(R.string.loan_account_details) + } + + override fun onNext(loanWithAssociations: LoanWithAssociations) { + if (loanWithAssociations.transactions != null && + loanWithAssociations.transactions?.isNotEmpty() == true + ) { + _loanUiState.value = LoanUiState.ShowLoan(loanWithAssociations) + } else { + _loanUiState.value = LoanUiState.ShowEmpty(loanWithAssociations) + } + } + })?.let { + compositeDisposables.add( + it, + ) + } + } + + override fun onCleared() { + super.onCleared() + compositeDisposables.clear() + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/LoanAccountWithdrawViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/LoanAccountWithdrawViewModel.kt new file mode 100644 index 000000000..9618b2f94 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/viewModels/LoanAccountWithdrawViewModel.kt @@ -0,0 +1,48 @@ +package org.mifos.mobile.viewModels + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.observers.DisposableObserver +import io.reactivex.schedulers.Schedulers +import okhttp3.ResponseBody +import org.mifos.mobile.R +import org.mifos.mobile.models.accounts.loan.LoanWithdraw +import org.mifos.mobile.repositories.LoanRepository +import org.mifos.mobile.utils.LoanUiState +import javax.inject.Inject + +@HiltViewModel +class LoanAccountWithdrawViewModel @Inject constructor(private val loanRepositoryImp: LoanRepository) : + ViewModel() { + + private val compositeDisposables: CompositeDisposable = CompositeDisposable() + + private val _loanUiState = MutableLiveData() + val loanUiState: LiveData get() = _loanUiState + + fun withdrawLoanAccount(loanId: Long?, loanWithdraw: LoanWithdraw?) { + _loanUiState.value = LoanUiState.Loading + loanRepositoryImp.withdrawLoanAccount(loanId, loanWithdraw) + ?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribeOn(Schedulers.io()) + ?.subscribeWith(object : DisposableObserver() { + override fun onComplete() {} + override fun onError(e: Throwable) { + _loanUiState.value = LoanUiState.ShowError(R.string.error_loan_account_withdraw) + } + + override fun onNext(responseBody: ResponseBody) { + _loanUiState.value = LoanUiState.WithdrawSuccess + } + })?.let { compositeDisposables.add(it) } + } + + override fun onCleared() { + super.onCleared() + compositeDisposables.clear() + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/LoanAccountsDetailViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/LoanAccountsDetailViewModel.kt new file mode 100644 index 000000000..3e0dfb83d --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/viewModels/LoanAccountsDetailViewModel.kt @@ -0,0 +1,55 @@ +package org.mifos.mobile.viewModels + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.observers.DisposableObserver +import io.reactivex.schedulers.Schedulers +import org.mifos.mobile.R +import org.mifos.mobile.models.accounts.loan.LoanWithAssociations +import org.mifos.mobile.repositories.LoanRepository +import org.mifos.mobile.utils.Constants +import org.mifos.mobile.utils.LoanUiState +import javax.inject.Inject + +@HiltViewModel +class LoanAccountsDetailViewModel @Inject constructor(private val loanRepositoryImp: LoanRepository) : + ViewModel() { + + private val compositeDisposables: CompositeDisposable = CompositeDisposable() + + private val _loanUiState = MutableLiveData() + val loanUiState: LiveData get() = _loanUiState + + fun loadLoanAccountDetails(loanId: Long?) { + _loanUiState.value = LoanUiState.Loading + loanRepositoryImp.getLoanWithAssociations( + Constants.REPAYMENT_SCHEDULE, + loanId, + )?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribeOn(Schedulers.io()) + ?.subscribeWith(object : DisposableObserver() { + override fun onComplete() {} + override fun onError(e: Throwable) { + _loanUiState.value = + LoanUiState.ShowError(R.string.loan_account_details) + } + + override fun onNext(loanWithAssociations: LoanWithAssociations) { + _loanUiState.value = LoanUiState.ShowLoan(loanWithAssociations) + } + })?.let { + compositeDisposables.add( + it, + ) + } + } + + override fun onCleared() { + super.onCleared() + compositeDisposables.clear() + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/LoanApplicationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/LoanApplicationViewModel.kt new file mode 100644 index 000000000..c9616779c --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/viewModels/LoanApplicationViewModel.kt @@ -0,0 +1,79 @@ +package org.mifos.mobile.viewModels + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.observers.DisposableObserver +import io.reactivex.schedulers.Schedulers +import org.mifos.mobile.R +import org.mifos.mobile.models.templates.loans.LoanTemplate +import org.mifos.mobile.repositories.LoanRepository +import org.mifos.mobile.ui.enums.LoanState +import org.mifos.mobile.utils.LoanUiState +import javax.inject.Inject + +@HiltViewModel +class LoanApplicationViewModel @Inject constructor(private val loanRepositoryImp: LoanRepository) : + ViewModel() { + + private val compositeDisposables: CompositeDisposable = CompositeDisposable() + + private val _loanUiState = MutableLiveData() + val loanUiState: LiveData get() = _loanUiState + + fun loadLoanApplicationTemplate(loanState: LoanState) { + _loanUiState.value = LoanUiState.Loading + loanRepositoryImp.template()?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribeOn(Schedulers.io()) + ?.subscribeWith(object : DisposableObserver() { + override fun onComplete() {} + override fun onError(e: Throwable) { + _loanUiState.value = LoanUiState.ShowError(R.string.error_fetching_template) + } + + override fun onNext(loanTemplate: LoanTemplate) { + if (loanState === LoanState.CREATE) { + _loanUiState.value = LoanUiState.ShowLoanTemplateByProduct(loanTemplate) + } else { + _loanUiState.value = LoanUiState.ShowUpdateLoanTemplateByProduct(loanTemplate) + } + } + })?.let { + compositeDisposables.add( + it, + ) + } + } + + fun loadLoanApplicationTemplateByProduct(productId: Int?, loanState: LoanState?) { + _loanUiState.value = LoanUiState.Loading + loanRepositoryImp.getLoanTemplateByProduct(productId)?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribeOn(Schedulers.io()) + ?.subscribeWith(object : DisposableObserver() { + override fun onComplete() {} + override fun onError(e: Throwable) { + _loanUiState.value = LoanUiState.ShowError(R.string.error_fetching_template) + } + + override fun onNext(loanTemplate: LoanTemplate) { + if (loanState === LoanState.CREATE) { + _loanUiState.value = LoanUiState.ShowLoanTemplate(loanTemplate) + } else { + _loanUiState.value = LoanUiState.ShowUpdateLoanTemplate(loanTemplate) + } + } + })?.let { + compositeDisposables.add( + it, + ) + } + } + + override fun onCleared() { + super.onCleared() + compositeDisposables.clear() + } +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/LoanRepaymentScheduleViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/LoanRepaymentScheduleViewModel.kt new file mode 100644 index 000000000..cb023919e --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/viewModels/LoanRepaymentScheduleViewModel.kt @@ -0,0 +1,61 @@ +package org.mifos.mobile.viewModels + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.observers.DisposableObserver +import io.reactivex.schedulers.Schedulers +import org.mifos.mobile.R +import org.mifos.mobile.models.accounts.loan.LoanWithAssociations +import org.mifos.mobile.repositories.LoanRepository +import org.mifos.mobile.utils.Constants +import org.mifos.mobile.utils.LoanUiState +import javax.inject.Inject + +@HiltViewModel +class LoanRepaymentScheduleViewModel @Inject constructor(private val loanRepositoryImp: LoanRepository) : + ViewModel() { + + private val compositeDisposables: CompositeDisposable = CompositeDisposable() + + private val _loanUiState = MutableLiveData() + val loanUiState: LiveData get() = _loanUiState + + fun loanLoanWithAssociations(loanId: Long?) { + _loanUiState.value = LoanUiState.Loading + loanRepositoryImp.getLoanWithAssociations( + Constants.REPAYMENT_SCHEDULE, + loanId, + )?.observeOn(AndroidSchedulers.mainThread()) + ?.subscribeOn(Schedulers.io()) + ?.subscribeWith(object : DisposableObserver() { + override fun onComplete() {} + override fun onError(e: Throwable) { + _loanUiState.value = + LoanUiState.ShowError(R.string.repayment_schedule) + } + + override fun onNext(loanWithAssociations: LoanWithAssociations) { + if (loanWithAssociations.repaymentSchedule?.periods?.isNotEmpty() == true) { + _loanUiState.value = + LoanUiState.ShowLoan(loanWithAssociations) + } else { + _loanUiState.value = + LoanUiState.ShowEmpty(loanWithAssociations) + } + } + })?.let { + compositeDisposables.add( + it, + ) + } + } + + override fun onCleared() { + super.onCleared() + compositeDisposables.clear() + } +} \ No newline at end of file From d046bdfaafe041863101e0790ce7190bc084441d Mon Sep 17 00:00:00 2001 From: Pratyush Singh Date: Sun, 16 Jul 2023 00:59:21 +0530 Subject: [PATCH 32/35] feat: exhaustive when branch in fragments --- .../mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt | 1 + .../org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt | 1 + .../org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt | 1 + .../org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt | 1 + .../mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt | 1 + 5 files changed, 5 insertions(+) diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt index 0b4c3db26..98a3fb308 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountTransactionFragment.kt @@ -158,6 +158,7 @@ class LoanAccountTransactionFragment : BaseFragment() { hideProgress() showEmptyTransactions(it.loanWithAssociations) } + else -> throw IllegalStateException("Unexpected state: $it") } } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt index 54e4abdbf..36c3ca519 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountWithdrawFragment.kt @@ -62,6 +62,7 @@ class LoanAccountWithdrawFragment : BaseFragment() { hideProgress() showLoanAccountWithdrawSuccess() } + else -> throw IllegalStateException("Unexpected state: $it") } } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt index 73f850b6a..755bb5b47 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanAccountsDetailFragment.kt @@ -178,6 +178,7 @@ class LoanAccountsDetailFragment : BaseFragment() { hideProgress() showLoanAccountsDetail(it.loanWithAssociations) } + else -> throw IllegalStateException("Unexpected state: $it") } } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt index 5c087cf83..397ead778 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanApplicationFragment.kt @@ -172,6 +172,7 @@ class LoanApplicationFragment : BaseFragment() { hideProgress() showUpdateLoanTemplateByProduct(it.template) } + else -> throw IllegalStateException("Unexpected state: $it") } } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt index 000b25836..95ec641a5 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/LoanRepaymentScheduleFragment.kt @@ -82,6 +82,7 @@ class LoanRepaymentScheduleFragment : BaseFragment() { hideProgress() showEmptyRepaymentsSchedule(loanWithAssociations) } + else -> throw IllegalStateException("Unexpected state: $it") } } From 23ff33738f210a46530acd5fe889252e70f6282e Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Sun, 16 Jul 2023 20:03:22 +0530 Subject: [PATCH 33/35] feat : udpatePassword mvvm migration -> renamed UiState to RegistrationUiState --- .../mobile/ui/fragments/RegistrationFragment.kt | 8 ++++---- .../ui/fragments/UpdatePasswordFragment.kt | 8 ++++---- .../mifos/mobile/utils/RegistrationUiState.kt | 7 +++++++ .../main/java/org/mifos/mobile/utils/UiState.kt | 7 ------- .../mobile/viewModels/RegistrationViewModel.kt | 12 ++++++------ .../mobile/viewModels/UpdatePasswordViewModel.kt | 12 ++++++------ .../repositories/ClientRepositoryImpTest.kt | 2 +- .../viewModels/RegistrationViewModelTest.kt | 16 ++++++++-------- .../viewModels/UpdatePasswordViewModelTest.kt | 12 ++++++------ 9 files changed, 42 insertions(+), 42 deletions(-) create mode 100644 app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt delete mode 100644 app/src/main/java/org/mifos/mobile/utils/UiState.kt diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt index 76b318e27..19a78ebc6 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationFragment.kt @@ -19,7 +19,7 @@ import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.utils.MFErrorParser import org.mifos.mobile.utils.Network import org.mifos.mobile.utils.PasswordStrength -import org.mifos.mobile.utils.UiState +import org.mifos.mobile.utils.RegistrationUiState import org.mifos.mobile.utils.Toaster import org.mifos.mobile.viewModels.RegistrationViewModel @@ -91,14 +91,14 @@ class RegistrationFragment : BaseFragment() { viewModel.registrationUiState.observe(viewLifecycleOwner) { state -> when (state) { - UiState.Loading -> showProgress() + RegistrationUiState.Loading -> showProgress() - UiState.Success -> { + RegistrationUiState.Success -> { hideProgress() showRegisteredSuccessfully() } - is UiState.Error -> { + is RegistrationUiState.Error -> { hideProgress() showError(MFErrorParser.errorMessage(state.exception)) } diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt index 3443d60a7..f1145f3a9 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/UpdatePasswordFragment.kt @@ -17,7 +17,7 @@ import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.utils.MFErrorParser import org.mifos.mobile.utils.Network import org.mifos.mobile.utils.Toaster -import org.mifos.mobile.utils.UiState +import org.mifos.mobile.utils.RegistrationUiState import org.mifos.mobile.viewModels.UpdatePasswordViewModel /* @@ -55,13 +55,13 @@ class UpdatePasswordFragment : BaseFragment(), TextWatcher, OnFocusChangeListene viewModel.updatePasswordUiState.observe(viewLifecycleOwner) { state -> when (state) { - UiState.Loading -> showProgress() - UiState.Success -> { + RegistrationUiState.Loading -> showProgress() + RegistrationUiState.Success -> { hideProgress() showPasswordUpdatedSuccessfully() } - is UiState.Error -> { + is RegistrationUiState.Error -> { hideProgress() showError(MFErrorParser.errorMessage(state.exception)) } diff --git a/app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt b/app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt new file mode 100644 index 000000000..a946db0b5 --- /dev/null +++ b/app/src/main/java/org/mifos/mobile/utils/RegistrationUiState.kt @@ -0,0 +1,7 @@ +package org.mifos.mobile.utils + +sealed class RegistrationUiState { + data class Error(val exception: Throwable) : RegistrationUiState() + object Success : RegistrationUiState() + object Loading : RegistrationUiState() +} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/utils/UiState.kt b/app/src/main/java/org/mifos/mobile/utils/UiState.kt deleted file mode 100644 index 5180a9059..000000000 --- a/app/src/main/java/org/mifos/mobile/utils/UiState.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.mifos.mobile.utils - -sealed class UiState { - data class Error(val exception: Throwable) : UiState() - object Success : UiState() - object Loading : UiState() -} \ No newline at end of file diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt index 2420a4c97..fd2a1b1dd 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt @@ -11,7 +11,7 @@ import io.reactivex.observers.DisposableObserver import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.mifos.mobile.repositories.UserAuthRepository -import org.mifos.mobile.utils.UiState +import org.mifos.mobile.utils.RegistrationUiState import javax.inject.Inject @HiltViewModel @@ -19,8 +19,8 @@ class RegistrationViewModel @Inject constructor(private val userAuthRepositoryIm ViewModel() { private val compositeDisposables: CompositeDisposable = CompositeDisposable() - private val _registrationUiState = MutableLiveData() - val registrationUiState: LiveData get() = _registrationUiState + private val _registrationUiState = MutableLiveData() + val registrationUiState: LiveData get() = _registrationUiState fun isInputFieldBlank(fieldText: String): Boolean { return fieldText.trim().isEmpty() @@ -52,7 +52,7 @@ class RegistrationViewModel @Inject constructor(private val userAuthRepositoryIm password: String, username: String ) { - _registrationUiState.value = UiState.Loading + _registrationUiState.value = RegistrationUiState.Loading userAuthRepositoryImp.registerUser( accountNumber, authenticationMode, @@ -66,11 +66,11 @@ class RegistrationViewModel @Inject constructor(private val userAuthRepositoryIm ?.subscribeWith(object : DisposableObserver() { override fun onComplete() {} override fun onError(e: Throwable) { - _registrationUiState.value = UiState.Error(e) + _registrationUiState.value = RegistrationUiState.Error(e) } override fun onNext(responseBody: ResponseBody) { - _registrationUiState.value = UiState.Success + _registrationUiState.value = RegistrationUiState.Success } })?.let { compositeDisposables.add(it) } } diff --git a/app/src/main/java/org/mifos/mobile/viewModels/UpdatePasswordViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/UpdatePasswordViewModel.kt index 747485278..cf9ae264b 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/UpdatePasswordViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/UpdatePasswordViewModel.kt @@ -11,7 +11,7 @@ import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.mifos.mobile.repositories.ClientRepository import org.mifos.mobile.repositories.UserAuthRepository -import org.mifos.mobile.utils.UiState +import org.mifos.mobile.utils.RegistrationUiState import javax.inject.Inject @HiltViewModel @@ -21,8 +21,8 @@ class UpdatePasswordViewModel @Inject constructor( ) : ViewModel() { private val compositeDisposable = CompositeDisposable() - private val _updatePasswordUiState = MutableLiveData() - val updatePasswordUiState: LiveData get() = _updatePasswordUiState + private val _updatePasswordUiState = MutableLiveData() + val updatePasswordUiState: LiveData get() = _updatePasswordUiState fun isInputFieldEmpty(fieldText: String): Boolean { return fieldText.isEmpty() } @@ -36,18 +36,18 @@ class UpdatePasswordViewModel @Inject constructor( } fun updateAccountPassword(newPassword: String, confirmPassword: String) { - _updatePasswordUiState.value = UiState.Loading + _updatePasswordUiState.value = RegistrationUiState.Loading userAuthRepositoryImp.updateAccountPassword(newPassword, confirmPassword) ?.subscribeOn(Schedulers.io()) ?.observeOn(AndroidSchedulers.mainThread()) ?.subscribeWith(object : DisposableObserver() { override fun onNext(responseBody: ResponseBody) { - _updatePasswordUiState.value = UiState.Success + _updatePasswordUiState.value = RegistrationUiState.Success clientRepositoryImp.updateAuthenticationToken(newPassword) } override fun onError(e: Throwable) { - _updatePasswordUiState.value = UiState.Error(e) + _updatePasswordUiState.value = RegistrationUiState.Error(e) } override fun onComplete() {} diff --git a/app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt b/app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt index 7ded8c55e..ce384c1c4 100644 --- a/app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt +++ b/app/src/test/java/org/mifos/mobile/repositories/ClientRepositoryImpTest.kt @@ -26,7 +26,7 @@ class ClientRepositoryImpTest { } @Test - fun test() { + fun testUpdateAuthenticationToken() { val mockPassword = "testPassword" val mockUsername = "testUsername" Mockito.`when`(preferencesHelper.userName).thenReturn(mockUsername) diff --git a/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt index 9c3160bf4..b815f9a3b 100644 --- a/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt +++ b/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt @@ -12,7 +12,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mifos.mobile.repositories.UserAuthRepositoryImp import org.mifos.mobile.util.RxSchedulersOverrideRule -import org.mifos.mobile.utils.UiState +import org.mifos.mobile.utils.RegistrationUiState import org.mockito.Mock import org.mockito.Mockito import org.mockito.MockitoAnnotations @@ -33,7 +33,7 @@ class RegistrationViewModelTest { lateinit var userAuthRepositoryImp: UserAuthRepositoryImp @Mock - lateinit var registrationUiStateObserver: Observer + lateinit var registrationUiStateObserver: Observer private lateinit var registrationViewModel: RegistrationViewModel @@ -70,7 +70,7 @@ class RegistrationViewModelTest { @Test fun testInputHasSpaces_WithSpacesInput_ReturnsTrue() { - val result = registrationViewModel.inputHasSpaces("test string") + val result = registrationViewModel.inputHasSpaces("testUpdateAuthenticationToken string") Assert.assertTrue(result) } @@ -94,7 +94,7 @@ class RegistrationViewModelTest { @Test fun testIsEmailInvalid_WithValidEmailInput_ReturnsFalse() { - val result = registrationViewModel.isEmailInvalid("test@example.com") + val result = registrationViewModel.isEmailInvalid("testUpdateAuthenticationToken@example.com") Assert.assertFalse(result) } @@ -127,8 +127,8 @@ class RegistrationViewModelTest { "userName" ) - Mockito.verify(registrationUiStateObserver).onChanged(UiState.Loading) - Mockito.verify(registrationUiStateObserver).onChanged(UiState.Success) + Mockito.verify(registrationUiStateObserver).onChanged(RegistrationUiState.Loading) + Mockito.verify(registrationUiStateObserver).onChanged(RegistrationUiState.Success) Mockito.verifyNoMoreInteractions(registrationUiStateObserver) } @@ -159,8 +159,8 @@ class RegistrationViewModelTest { "username" ) - Mockito.verify(registrationUiStateObserver).onChanged(UiState.Loading) - Mockito.verify(registrationUiStateObserver).onChanged(UiState.Error(error)) + Mockito.verify(registrationUiStateObserver).onChanged(RegistrationUiState.Loading) + Mockito.verify(registrationUiStateObserver).onChanged(RegistrationUiState.Error(error)) Mockito.verifyNoMoreInteractions(registrationUiStateObserver) } diff --git a/app/src/test/java/org/mifos/mobile/viewModels/UpdatePasswordViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/UpdatePasswordViewModelTest.kt index e31fbe326..d1014b4a5 100644 --- a/app/src/test/java/org/mifos/mobile/viewModels/UpdatePasswordViewModelTest.kt +++ b/app/src/test/java/org/mifos/mobile/viewModels/UpdatePasswordViewModelTest.kt @@ -14,7 +14,7 @@ import org.junit.runner.RunWith import org.mifos.mobile.repositories.ClientRepository import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.util.RxSchedulersOverrideRule -import org.mifos.mobile.utils.UiState +import org.mifos.mobile.utils.RegistrationUiState import org.mockito.Mock import org.mockito.Mockito import org.mockito.MockitoAnnotations @@ -38,7 +38,7 @@ class UpdatePasswordViewModelTest { lateinit var clientRepositoryImp: ClientRepository @Mock - private lateinit var updatePasswordUiStateObserver: Observer + private lateinit var updatePasswordUiStateObserver: Observer private lateinit var updatePasswordViewModel: UpdatePasswordViewModel @@ -94,8 +94,8 @@ class UpdatePasswordViewModelTest { ).thenReturn(Observable.just(responseBody)) updatePasswordViewModel.updateAccountPassword("newPassword", "newPassword") - Mockito.verify(updatePasswordUiStateObserver).onChanged(UiState.Loading) - Mockito.verify(updatePasswordUiStateObserver).onChanged(UiState.Success) + Mockito.verify(updatePasswordUiStateObserver).onChanged(RegistrationUiState.Loading) + Mockito.verify(updatePasswordUiStateObserver).onChanged(RegistrationUiState.Success) Mockito.verify(clientRepositoryImp).updateAuthenticationToken("newPassword") Mockito.verifyNoMoreInteractions(updatePasswordUiStateObserver) } @@ -109,8 +109,8 @@ class UpdatePasswordViewModelTest { updatePasswordViewModel.updateAccountPassword("newPassword", "newPassword") - Mockito.verify(updatePasswordUiStateObserver).onChanged(UiState.Loading) - Mockito.verify(updatePasswordUiStateObserver).onChanged(UiState.Error(error)) + Mockito.verify(updatePasswordUiStateObserver).onChanged(RegistrationUiState.Loading) + Mockito.verify(updatePasswordUiStateObserver).onChanged(RegistrationUiState.Error(error)) Mockito.verifyNoMoreInteractions(updatePasswordUiStateObserver) } From 4bb68387ee52fb48a8ff248402aec5c2936e8ab2 Mon Sep 17 00:00:00 2001 From: gururani-abhishek Date: Mon, 17 Jul 2023 17:14:25 +0530 Subject: [PATCH 34/35] feat : registration verification mvvm migration -> deleted extra RegistrationVerificationUiState and used RegistrationUiState instead. --- .../ui/fragments/RegistrationVerificationFragment.kt | 8 ++++---- .../mobile/utils/RegistrationVerificationUiState.kt | 8 -------- .../mifos/mobile/viewModels/RegistrationViewModel.kt | 11 +++++------ .../mobile/viewModels/RegistrationViewModelTest.kt | 11 +++++------ 4 files changed, 14 insertions(+), 24 deletions(-) delete mode 100644 app/src/main/java/org/mifos/mobile/utils/RegistrationVerificationUiState.kt diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt index c45b2dbe2..7b793d8fd 100644 --- a/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt +++ b/app/src/main/java/org/mifos/mobile/ui/fragments/RegistrationVerificationFragment.kt @@ -13,7 +13,7 @@ import org.mifos.mobile.databinding.FragmentRegistrationVerificationBinding import org.mifos.mobile.ui.activities.LoginActivity import org.mifos.mobile.ui.fragments.base.BaseFragment import org.mifos.mobile.utils.MFErrorParser -import org.mifos.mobile.utils.RegistrationVerificationUiState +import org.mifos.mobile.utils.RegistrationUiState import org.mifos.mobile.utils.Toaster import org.mifos.mobile.viewModels.RegistrationViewModel @@ -42,14 +42,14 @@ class RegistrationVerificationFragment : BaseFragment() { viewModel.registrationVerificationUiState.observe(viewLifecycleOwner) { state -> when (state) { - RegistrationVerificationUiState.Loading -> showProgress() + RegistrationUiState.Loading -> showProgress() - RegistrationVerificationUiState.RegistrationVerificationSuccessful -> { + RegistrationUiState.Success -> { hideProgress() showVerifiedSuccessfully() } - is RegistrationVerificationUiState.ErrorOnRegistrationVerification -> { + is RegistrationUiState.Error -> { hideProgress() showError(MFErrorParser.errorMessage(state.exception)) } diff --git a/app/src/main/java/org/mifos/mobile/utils/RegistrationVerificationUiState.kt b/app/src/main/java/org/mifos/mobile/utils/RegistrationVerificationUiState.kt deleted file mode 100644 index 25506244b..000000000 --- a/app/src/main/java/org/mifos/mobile/utils/RegistrationVerificationUiState.kt +++ /dev/null @@ -1,8 +0,0 @@ -package org.mifos.mobile.utils - -sealed class RegistrationVerificationUiState { - object Loading : RegistrationVerificationUiState() - object RegistrationVerificationSuccessful : RegistrationVerificationUiState() - data class ErrorOnRegistrationVerification(val exception: Throwable) : - RegistrationVerificationUiState() -} diff --git a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt index 9bb2329eb..ecdbd4a93 100644 --- a/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt +++ b/app/src/main/java/org/mifos/mobile/viewModels/RegistrationViewModel.kt @@ -12,7 +12,6 @@ import io.reactivex.schedulers.Schedulers import okhttp3.ResponseBody import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.utils.RegistrationUiState -import org.mifos.mobile.utils.RegistrationVerificationUiState import javax.inject.Inject @HiltViewModel @@ -24,8 +23,8 @@ class RegistrationViewModel @Inject constructor(private val userAuthRepositoryIm val registrationUiState: LiveData get() = _registrationUiState private val _registrationVerificationUiState = - MutableLiveData() - val registrationVerificationUiState: LiveData get() = _registrationVerificationUiState + MutableLiveData() + val registrationVerificationUiState: LiveData get() = _registrationVerificationUiState fun isInputFieldBlank(fieldText: String): Boolean { return fieldText.trim().isEmpty() @@ -81,19 +80,19 @@ class RegistrationViewModel @Inject constructor(private val userAuthRepositoryIm } fun verifyUser(authenticationToken: String?, requestId: String?) { - _registrationVerificationUiState.value = RegistrationVerificationUiState.Loading + _registrationVerificationUiState.value = RegistrationUiState.Loading userAuthRepositoryImp.verifyUser(authenticationToken, requestId)?.observeOn(AndroidSchedulers.mainThread()) ?.subscribeOn(Schedulers.io()) ?.subscribeWith(object : DisposableObserver() { override fun onComplete() {} override fun onError(e: Throwable) { _registrationVerificationUiState.value = - RegistrationVerificationUiState.ErrorOnRegistrationVerification(e) + RegistrationUiState.Error(e) } override fun onNext(responseBody: ResponseBody) { _registrationVerificationUiState.value = - RegistrationVerificationUiState.RegistrationVerificationSuccessful + RegistrationUiState.Success } })?.let { compositeDisposables.add(it) } } diff --git a/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt index b27cc00f1..322322961 100644 --- a/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt +++ b/app/src/test/java/org/mifos/mobile/viewModels/RegistrationViewModelTest.kt @@ -13,7 +13,6 @@ import org.junit.runner.RunWith import org.mifos.mobile.repositories.UserAuthRepository import org.mifos.mobile.util.RxSchedulersOverrideRule import org.mifos.mobile.utils.RegistrationUiState -import org.mifos.mobile.utils.RegistrationVerificationUiState import org.mockito.Mock import org.mockito.Mockito import org.mockito.MockitoAnnotations @@ -37,7 +36,7 @@ class RegistrationViewModelTest { lateinit var registrationUiStateObserver: Observer @Mock - lateinit var registrationVerificationUiStateObserver: Observer + lateinit var registrationVerificationUiStateObserver: Observer private lateinit var registrationViewModel: RegistrationViewModel @@ -180,9 +179,9 @@ class RegistrationViewModelTest { registrationViewModel.verifyUser("authenticationToken", "requestId") Mockito.verify(registrationVerificationUiStateObserver) - .onChanged(RegistrationVerificationUiState.Loading) + .onChanged(RegistrationUiState.Loading) Mockito.verify(registrationVerificationUiStateObserver) - .onChanged(RegistrationVerificationUiState.RegistrationVerificationSuccessful) + .onChanged(RegistrationUiState.Success) Mockito.verifyNoMoreInteractions(registrationUiStateObserver) } @@ -196,9 +195,9 @@ class RegistrationViewModelTest { registrationViewModel.verifyUser("authenticationToken", "requestId") Mockito.verify(registrationVerificationUiStateObserver) - .onChanged(RegistrationVerificationUiState.Loading) + .onChanged(RegistrationUiState.Loading) Mockito.verify(registrationVerificationUiStateObserver) - .onChanged(RegistrationVerificationUiState.ErrorOnRegistrationVerification(error)) + .onChanged(RegistrationUiState.Error(error)) Mockito.verifyNoMoreInteractions(registrationUiStateObserver) } From eb0c52cf749e3fd0ed430970beff7f052844b0f0 Mon Sep 17 00:00:00 2001 From: Pratyush Singh Date: Fri, 21 Jul 2023 16:25:12 +0530 Subject: [PATCH 35/35] feat: tests for repositories and viewmodels --- .../repositories/LoanRepositoryImpTest.kt | 142 ++++++++++++++++++ .../LoanAccountTransactionViewModelTest.kt | 103 +++++++++++++ .../LoanAccountWithdrawViewModelTest.kt | 84 +++++++++++ .../LoanAccountsDetailViewModelTest.kt | 85 +++++++++++ .../LoanApplicationViewModelTest.kt | 117 +++++++++++++++ .../LoanRepaymentScheduleViewModelTest.kt | 90 +++++++++++ 6 files changed, 621 insertions(+) create mode 100644 app/src/test/java/org/mifos/mobile/repositories/LoanRepositoryImpTest.kt create mode 100644 app/src/test/java/org/mifos/mobile/viewModels/LoanAccountTransactionViewModelTest.kt create mode 100644 app/src/test/java/org/mifos/mobile/viewModels/LoanAccountWithdrawViewModelTest.kt create mode 100644 app/src/test/java/org/mifos/mobile/viewModels/LoanAccountsDetailViewModelTest.kt create mode 100644 app/src/test/java/org/mifos/mobile/viewModels/LoanApplicationViewModelTest.kt create mode 100644 app/src/test/java/org/mifos/mobile/viewModels/LoanRepaymentScheduleViewModelTest.kt diff --git a/app/src/test/java/org/mifos/mobile/repositories/LoanRepositoryImpTest.kt b/app/src/test/java/org/mifos/mobile/repositories/LoanRepositoryImpTest.kt new file mode 100644 index 000000000..266c2da9e --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/repositories/LoanRepositoryImpTest.kt @@ -0,0 +1,142 @@ +package org.mifos.mobile.repositories + +import io.reactivex.Observable +import junit.framework.Assert.assertEquals +import okhttp3.ResponseBody +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mifos.mobile.api.DataManager +import org.mifos.mobile.models.accounts.loan.LoanWithAssociations +import org.mifos.mobile.models.accounts.loan.LoanWithdraw +import org.mifos.mobile.models.templates.loans.LoanTemplate +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.Mockito.`when` +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner + +@RunWith(MockitoJUnitRunner::class) +class LoanRepositoryImpTest { + @Mock + lateinit var dataManager: DataManager + + @Mock + lateinit var loanWithdraw: LoanWithdraw + + private lateinit var loanRepositoryImp: LoanRepositoryImp + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + loanRepositoryImp = LoanRepositoryImp(dataManager) + } + + @Test + fun testGetLoanWithAssociations_Successful() { + val success: Observable = + Observable.just(Mockito.mock(LoanWithAssociations::class.java)) + + `when`( + dataManager.getLoanWithAssociations( + Mockito.anyString(), + Mockito.anyLong() + ) + ).thenReturn(success) + + val result = loanRepositoryImp.getLoanWithAssociations( + "associationType", + 1 + ) + verify(dataManager).getLoanWithAssociations(Mockito.anyString(), Mockito.anyLong()) + assertEquals(result, success) + } + + @Test + fun testGetLoanWithAssociations_Unsuccessful() { + val error: Observable = + Observable.error(Throwable("Failed to fetch loan with associations")) + `when`( + dataManager.getLoanWithAssociations( + Mockito.anyString(), + Mockito.anyLong() + ) + ).thenReturn(error) + + val result = loanRepositoryImp.getLoanWithAssociations( + "associationType", + 1 + ) + + verify(dataManager).getLoanWithAssociations(Mockito.anyString(), Mockito.anyLong()) + assertEquals(result, error) + } + + @Test + fun testWithdrawLoanAccount_Successful() { + val success: Observable = + Observable.just(Mockito.mock(ResponseBody::class.java)) + + `when`(dataManager.withdrawLoanAccount(1, loanWithdraw)).thenReturn(success) + + val result = loanRepositoryImp.withdrawLoanAccount(1, loanWithdraw) + verify(dataManager).withdrawLoanAccount(1, loanWithdraw) + assertEquals(result, success) + } + + @Test + fun testWithdrawLoanAccount_Unsuccessful() { + val error: Observable = + Observable.error(Throwable("Failed to withdraw loan account")) + `when`(dataManager.withdrawLoanAccount(1, loanWithdraw)).thenReturn(error) + + val result = loanRepositoryImp.withdrawLoanAccount(1, loanWithdraw) + verify(dataManager).withdrawLoanAccount(1, loanWithdraw) + assertEquals(result, error) + } + + @Test + fun testTemplate_Successful() { + val success: Observable = + Observable.just(Mockito.mock(LoanTemplate::class.java)) + `when`(dataManager.loanTemplate).thenReturn(success) + + val result = loanRepositoryImp.template() + verify(dataManager).loanTemplate + assertEquals(result, success) + } + + @Test + fun testTemplate_Unsuccessful() { + val error: Observable = + Observable.error(Throwable("Failed to load template")) + `when`(dataManager.loanTemplate).thenReturn(error) + + val result = loanRepositoryImp.template() + verify(dataManager).loanTemplate + assertEquals(result, error) + } + + @Test + fun testGetLoanTemplateByProduct_Successful() { + val success: Observable = + Observable.just(Mockito.mock(LoanTemplate::class.java)) + `when`(dataManager.getLoanTemplateByProduct(1)).thenReturn(success) + + val result = loanRepositoryImp.getLoanTemplateByProduct(1) + verify(dataManager).getLoanTemplateByProduct(1) + assertEquals(result, success) + } + + @Test + fun testGetLoanTemplateByProduct_Unsuccessful() { + val error: Observable = + Observable.error(Throwable("Failed to get loan template by product")) + `when`(dataManager.getLoanTemplateByProduct(1)).thenReturn(error) + + val result = loanRepositoryImp.getLoanTemplateByProduct(1) + verify(dataManager).getLoanTemplateByProduct(1) + assertEquals(result, error) + } +} \ No newline at end of file diff --git a/app/src/test/java/org/mifos/mobile/viewModels/LoanAccountTransactionViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/LoanAccountTransactionViewModelTest.kt new file mode 100644 index 000000000..7f7e49a7d --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/viewModels/LoanAccountTransactionViewModelTest.kt @@ -0,0 +1,103 @@ +package org.mifos.mobile.viewModels + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import androidx.lifecycle.Observer +import io.reactivex.Observable +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mifos.mobile.models.accounts.loan.LoanWithAssociations +import org.mifos.mobile.repositories.LoanRepositoryImp +import org.mifos.mobile.util.RxSchedulersOverrideRule +import org.mifos.mobile.utils.Constants +import org.mifos.mobile.utils.LoanUiState +import org.mockito.Mock +import org.mifos.mobile.R +import org.mockito.Mockito.* +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner + +@RunWith(MockitoJUnitRunner::class) +class LoanAccountTransactionViewModelTest { + + @JvmField + @Rule + val mOverrideSchedulersRule = RxSchedulersOverrideRule() + + @get:Rule + val rule = InstantTaskExecutorRule() + + @Mock + lateinit var loanRepositoryImp: LoanRepositoryImp + + @Mock + lateinit var loanUiStateObserver: Observer + + private lateinit var viewModel: LoanAccountTransactionViewModel + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + viewModel = LoanAccountTransactionViewModel(loanRepositoryImp) + viewModel.loanUiState.observeForever(loanUiStateObserver) + } + + @Test + fun testLoadLoanAccountDetails_Successful_WithEmptyTransaction() { + val response = mock(LoanWithAssociations::class.java) + `when`( + loanRepositoryImp.getLoanWithAssociations( + Constants.TRANSACTIONS, + 1 + ) + ).thenReturn(Observable.just(response)) + + viewModel.loadLoanAccountDetails(1) + verify(loanUiStateObserver).onChanged(LoanUiState.Loading) + verify(loanUiStateObserver).onChanged(LoanUiState.ShowEmpty(response)) + verifyNoMoreInteractions(loanUiStateObserver) + } + + @Test + fun testLoadLoanAccountDetails_Successful_WithNonEmptyTransaction() { + val response = mock(LoanWithAssociations::class.java) + + `when`( + loanRepositoryImp.getLoanWithAssociations( + Constants.TRANSACTIONS, + 1 + ) + ).thenReturn(Observable.just(response)) + + viewModel.loadLoanAccountDetails(1) + verify(loanUiStateObserver).onChanged(LoanUiState.Loading) + if (response.transactions != null && response?.transactions?.isNotEmpty() == true) { + verify(loanUiStateObserver).onChanged(LoanUiState.ShowLoan(response)) + verifyNoMoreInteractions(loanUiStateObserver) + } + } + + @Test + fun testLoadLoanAccountDetails_Unsuccessful() { + val error = RuntimeException("Error Response") + `when`( + loanRepositoryImp.getLoanWithAssociations( + Constants.TRANSACTIONS, + 1 + ) + ).thenReturn(Observable.error(error)) + + viewModel.loadLoanAccountDetails(1) + verify(loanUiStateObserver).onChanged(LoanUiState.Loading) + verify(loanUiStateObserver).onChanged(LoanUiState.ShowError(R.string.loan_account_details)) + verifyNoMoreInteractions(loanUiStateObserver) + } + + @After + fun tearDown() { + viewModel.loanUiState.removeObserver(loanUiStateObserver) + } + +} \ No newline at end of file diff --git a/app/src/test/java/org/mifos/mobile/viewModels/LoanAccountWithdrawViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/LoanAccountWithdrawViewModelTest.kt new file mode 100644 index 000000000..a3c945259 --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/viewModels/LoanAccountWithdrawViewModelTest.kt @@ -0,0 +1,84 @@ +package org.mifos.mobile.viewModels + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import androidx.lifecycle.Observer +import io.reactivex.Observable +import okhttp3.ResponseBody +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mifos.mobile.models.accounts.loan.LoanWithdraw +import org.mifos.mobile.repositories.LoanRepositoryImp +import org.mifos.mobile.util.RxSchedulersOverrideRule +import org.mifos.mobile.utils.LoanUiState +import org.mockito.Mock +import org.mifos.mobile.R +import org.mockito.Mockito.* +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner + +@RunWith(MockitoJUnitRunner::class) +class LoanAccountWithdrawViewModelTest { + + @JvmField + @Rule + val mOverrideSchedulersRule = RxSchedulersOverrideRule() + + @get:Rule + val rule = InstantTaskExecutorRule() + + @Mock + lateinit var loanRepositoryImp: LoanRepositoryImp + + @Mock + lateinit var loanUiStateObserver: Observer + + private lateinit var viewModel: LoanAccountWithdrawViewModel + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + viewModel = LoanAccountWithdrawViewModel(loanRepositoryImp) + viewModel.loanUiState.observeForever(loanUiStateObserver) + } + + @Test + fun testWithdrawLoanAccount_Successful() { + val response = mock(ResponseBody::class.java) + val mockLoanWithdraw = mock(LoanWithdraw::class.java) + `when`( + loanRepositoryImp.withdrawLoanAccount( + 1, + mockLoanWithdraw + ) + ).thenReturn(Observable.just(response)) + viewModel.withdrawLoanAccount(1, mockLoanWithdraw) + verify(loanUiStateObserver).onChanged(LoanUiState.Loading) + verify(loanUiStateObserver).onChanged(LoanUiState.WithdrawSuccess) + verifyNoMoreInteractions(loanUiStateObserver) + } + + @Test + fun testWithdrawLoanAccount_Unsuccessful() { + val error = RuntimeException("Error Response") + val mockLoanWithdraw = mock(LoanWithdraw::class.java) + `when`( + loanRepositoryImp.withdrawLoanAccount( + 1, + mockLoanWithdraw + ) + ).thenReturn(Observable.error(error)) + viewModel.withdrawLoanAccount(1, mockLoanWithdraw) + verify(loanUiStateObserver).onChanged(LoanUiState.Loading) + verify(loanUiStateObserver).onChanged(LoanUiState.ShowError(R.string.error_loan_account_withdraw)) + verifyNoMoreInteractions(loanUiStateObserver) + } + + @After + fun tearDown() { + viewModel.loanUiState.removeObserver(loanUiStateObserver) + } + +} \ No newline at end of file diff --git a/app/src/test/java/org/mifos/mobile/viewModels/LoanAccountsDetailViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/LoanAccountsDetailViewModelTest.kt new file mode 100644 index 000000000..f2bcf7164 --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/viewModels/LoanAccountsDetailViewModelTest.kt @@ -0,0 +1,85 @@ +package org.mifos.mobile.viewModels + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import androidx.lifecycle.Observer +import io.reactivex.Observable +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mifos.mobile.R +import org.mifos.mobile.models.accounts.loan.LoanWithAssociations +import org.mifos.mobile.repositories.LoanRepositoryImp +import org.mifos.mobile.util.RxSchedulersOverrideRule +import org.mifos.mobile.utils.Constants +import org.mifos.mobile.utils.LoanUiState +import org.mockito.Mock +import org.mockito.Mockito.* +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner + + +@RunWith(MockitoJUnitRunner::class) +class LoanAccountsDetailViewModelTest { + + @JvmField + @Rule + val mOverrideSchedulersRule = RxSchedulersOverrideRule() + + @get:Rule + val rule = InstantTaskExecutorRule() + + @Mock + lateinit var loanRepositoryImp: LoanRepositoryImp + + @Mock + lateinit var loanUiStateObserver: Observer + + lateinit var viewModel: LoanAccountsDetailViewModel + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + viewModel = LoanAccountsDetailViewModel(loanRepositoryImp) + viewModel.loanUiState.observeForever(loanUiStateObserver) + } + + @Test + fun testLoadLoanAccountDetails_Successful() { + val response = mock(LoanWithAssociations::class.java) + + `when`( + loanRepositoryImp.getLoanWithAssociations( + Constants.REPAYMENT_SCHEDULE, + 1 + ) + ).thenReturn(Observable.just(response)) + + viewModel.loadLoanAccountDetails(1) + verify(loanUiStateObserver).onChanged(LoanUiState.Loading) + verify(loanUiStateObserver).onChanged(LoanUiState.ShowLoan(response)) + verifyNoMoreInteractions(loanUiStateObserver) + } + + @Test + fun testLoadLoanAccountDetails_Unsuccessful() { + val error = RuntimeException("Error Response") + `when`( + loanRepositoryImp.getLoanWithAssociations( + Constants.REPAYMENT_SCHEDULE, + 1 + ) + ).thenReturn(Observable.error(error)) + + viewModel.loadLoanAccountDetails(1) + verify(loanUiStateObserver).onChanged(LoanUiState.Loading) + verify(loanUiStateObserver).onChanged(LoanUiState.ShowError(R.string.loan_account_details)) + verifyNoMoreInteractions(loanUiStateObserver) + } + + @After + fun tearDown() { + viewModel.loanUiState.removeObserver(loanUiStateObserver) + } +} \ No newline at end of file diff --git a/app/src/test/java/org/mifos/mobile/viewModels/LoanApplicationViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/LoanApplicationViewModelTest.kt new file mode 100644 index 000000000..93984dda6 --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/viewModels/LoanApplicationViewModelTest.kt @@ -0,0 +1,117 @@ +package org.mifos.mobile.viewModels + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import androidx.lifecycle.Observer +import io.reactivex.Observable +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mifos.mobile.R +import org.mifos.mobile.models.templates.loans.LoanTemplate +import org.mifos.mobile.repositories.LoanRepositoryImp +import org.mifos.mobile.ui.enums.LoanState +import org.mifos.mobile.util.RxSchedulersOverrideRule +import org.mifos.mobile.utils.LoanUiState +import org.mockito.Mock +import org.mockito.Mockito.* +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner + +@RunWith(MockitoJUnitRunner::class) +class LoanApplicationViewModelTest { + + @JvmField + @Rule + val mOverrideSchedulersRule = RxSchedulersOverrideRule() + + @get:Rule + val rule = InstantTaskExecutorRule() + + @Mock + lateinit var loanRepositoryImp: LoanRepositoryImp + + @Mock + lateinit var loanUiStateObserver: Observer + + private lateinit var viewModel: LoanApplicationViewModel + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + viewModel = LoanApplicationViewModel(loanRepositoryImp) + viewModel.loanUiState.observeForever(loanUiStateObserver) + } + + @Test + fun testLoadLoanApplicationTemplate_Successful() { + val response = mock(LoanTemplate::class.java) + val mockLoanState = mock(LoanState::class.java) + `when`(loanRepositoryImp.template()).thenReturn(Observable.just(response)) + viewModel.loadLoanApplicationTemplate(mockLoanState) + + verify(loanUiStateObserver).onChanged(LoanUiState.Loading) + if (mockLoanState == LoanState.CREATE) { + verify(loanUiStateObserver).onChanged(LoanUiState.ShowLoanTemplateByProduct(response)) + verifyNoMoreInteractions(loanUiStateObserver) + } else { + verify(loanUiStateObserver).onChanged( + LoanUiState.ShowUpdateLoanTemplateByProduct( + response + ) + ) + verifyNoMoreInteractions(loanUiStateObserver) + } + } + + @Test + fun testLoadLoanApplicationTemplate_Unsuccessful() { + val error = RuntimeException("Error Response") + val loanState = mock(LoanState::class.java) + `when`(loanRepositoryImp.template()).thenReturn(Observable.error(error)) + viewModel.loadLoanApplicationTemplate(loanState) + verify(loanUiStateObserver).onChanged(LoanUiState.Loading) + verify(loanUiStateObserver).onChanged(LoanUiState.ShowError(R.string.error_fetching_template)) + verifyNoMoreInteractions(loanUiStateObserver) + } + + @Test + fun loadLoanApplicationTemplateByProduct_Successful() { + val response = mock(LoanTemplate::class.java) + val mockLoanState = mock(LoanState::class.java) + + `when`(loanRepositoryImp.getLoanTemplateByProduct(1)).thenReturn(Observable.just(response)) + viewModel.loadLoanApplicationTemplateByProduct(1, mockLoanState) + verify(loanUiStateObserver).onChanged(LoanUiState.Loading) + if (mockLoanState == LoanState.CREATE) { + verify(loanUiStateObserver).onChanged(LoanUiState.ShowLoanTemplate(response)) + verifyNoMoreInteractions(loanUiStateObserver) + } else { + verify(loanUiStateObserver).onChanged( + LoanUiState.ShowUpdateLoanTemplate( + response + ) + ) + verifyNoMoreInteractions(loanUiStateObserver) + } + + } + + @Test + fun loadLoanApplicationTemplateByProduct_Unsuccessful() { + val error = RuntimeException("Error Response") + val mockLoanState = mock(LoanState::class.java) + `when`(loanRepositoryImp.getLoanTemplateByProduct(1)).thenReturn(Observable.error(error)) + viewModel.loadLoanApplicationTemplateByProduct(1, mockLoanState) + verify(loanUiStateObserver).onChanged(LoanUiState.Loading) + verify(loanUiStateObserver).onChanged(LoanUiState.ShowError(R.string.error_fetching_template)) + verifyNoMoreInteractions(loanUiStateObserver) + } + + @After + fun tearDown() { + viewModel.loanUiState.removeObserver(loanUiStateObserver) + } + +} \ No newline at end of file diff --git a/app/src/test/java/org/mifos/mobile/viewModels/LoanRepaymentScheduleViewModelTest.kt b/app/src/test/java/org/mifos/mobile/viewModels/LoanRepaymentScheduleViewModelTest.kt new file mode 100644 index 000000000..d6fee83a5 --- /dev/null +++ b/app/src/test/java/org/mifos/mobile/viewModels/LoanRepaymentScheduleViewModelTest.kt @@ -0,0 +1,90 @@ +package org.mifos.mobile.viewModels + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import androidx.lifecycle.Observer +import io.reactivex.Observable +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mifos.mobile.models.accounts.loan.LoanWithAssociations +import org.mifos.mobile.repositories.LoanRepositoryImp +import org.mifos.mobile.util.RxSchedulersOverrideRule +import org.mifos.mobile.utils.Constants +import org.mifos.mobile.utils.LoanUiState +import org.mockito.Mock +import org.mifos.mobile.R +import org.mockito.Mockito.* +import org.mockito.MockitoAnnotations +import org.mockito.junit.MockitoJUnitRunner + +@RunWith(MockitoJUnitRunner::class) +class LoanRepaymentScheduleViewModelTest { + + @JvmField + @Rule + val mOverrideSchedulersRule = RxSchedulersOverrideRule() + + @get:Rule + val rule = InstantTaskExecutorRule() + + @Mock + lateinit var loanRepositoryImp: LoanRepositoryImp + + @Mock + lateinit var loanUiStateObserver: Observer + + private lateinit var viewModel: LoanRepaymentScheduleViewModel + + @Before + fun setUp() { + MockitoAnnotations.openMocks(this) + viewModel = LoanRepaymentScheduleViewModel(loanRepositoryImp) + viewModel.loanUiState.observeForever(loanUiStateObserver) + } + + @Test + fun testLoanLoanWithAssociations_Successful() { + val response = mock(LoanWithAssociations::class.java) + `when`( + loanRepositoryImp.getLoanWithAssociations( + Constants.REPAYMENT_SCHEDULE, + 1 + ) + ).thenReturn(Observable.just(response)) + + viewModel.loanLoanWithAssociations(1) + verify(loanUiStateObserver).onChanged(LoanUiState.Loading) + if (response.repaymentSchedule?.periods?.isNotEmpty() == true) { + verify(loanUiStateObserver).onChanged(LoanUiState.ShowLoan(response)) + verifyNoMoreInteractions(loanUiStateObserver) + } else { + verify(loanUiStateObserver).onChanged(LoanUiState.ShowEmpty(response)) + verifyNoMoreInteractions(loanUiStateObserver) + } + } + + @Test + fun testLoanLoanWithAssociations_Unsuccessful() { + val error = RuntimeException("Error Response") + `when`( + loanRepositoryImp.getLoanWithAssociations( + Constants.REPAYMENT_SCHEDULE, + 1 + ) + ).thenReturn( + Observable.error(error) + ) + viewModel.loanLoanWithAssociations(1) + verify(loanUiStateObserver).onChanged(LoanUiState.Loading) + verify(loanUiStateObserver).onChanged(LoanUiState.ShowError(R.string.repayment_schedule)) + } + + @After + fun tearDown() { + viewModel.loanUiState.removeObserver(loanUiStateObserver) + } + + +} \ No newline at end of file