Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.navigation.fragment.navArgs
import com.google.android.material.tabs.TabLayout
import com.simprints.feature.consent.R
import com.simprints.feature.consent.databinding.FragmentConsentBinding
import com.simprints.feature.consent.screens.consent.helpers.ConsentTextHelperFactory
import com.simprints.feature.exitform.ExitFormContract
import com.simprints.feature.exitform.ExitFormResult
import com.simprints.feature.exitform.toArgs
Expand All @@ -22,6 +23,7 @@ import com.simprints.infra.uibase.navigation.handleResult
import com.simprints.infra.uibase.navigation.navigateSafely
import com.simprints.infra.uibase.viewbinding.viewBinding
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
import com.simprints.infra.resources.R as IDR

@AndroidEntryPoint
Expand All @@ -31,8 +33,12 @@ internal class ConsentFragment : Fragment(R.layout.fragment_consent) {
private val binding by viewBinding(FragmentConsentBinding::bind)
private val viewModel by viewModels<ConsentViewModel>()

@Inject
internal lateinit var textHelperFactory: ConsentTextHelperFactory

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.init(textHelperFactory)

binding.consentPrivacyNotice.paintFlags =
binding.consentPrivacyNotice.paintFlags or Paint.UNDERLINE_TEXT_FLAG
Expand Down Expand Up @@ -113,7 +119,7 @@ internal class ConsentFragment : Fragment(R.layout.fragment_consent) {

private fun TabLayout.addParentalConsentTab(
generalConsentText: String,
parentalConsentText: String
parentalConsentText: String,
) {
addTab(newTab().setText(IDR.string.consent_parental_title), PARENTAL_CONSENT_TAB)
addOnTabSelectedListener(OnTabSelectedListener { tab ->
Expand All @@ -134,6 +140,7 @@ internal class ConsentFragment : Fragment(R.layout.fragment_consent) {
}

companion object {

private const val GENERAL_CONSENT_TAB = 0
private const val PARENTAL_CONSENT_TAB = 1
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.simprints.core.livedata.send
import com.simprints.core.tools.time.TimeHelper
import com.simprints.feature.consent.ConsentResult
import com.simprints.feature.consent.ConsentType
import com.simprints.feature.consent.screens.consent.helpers.ConsentTextHelperFactory
import com.simprints.feature.consent.screens.consent.helpers.GeneralConsentTextHelper
import com.simprints.feature.consent.screens.consent.helpers.ParentalConsentTextHelper
import com.simprints.feature.exitform.ExitFormConfigurationBuilder
Expand All @@ -33,13 +34,14 @@ internal class ConsentViewModel @Inject constructor(
private val timeHelper: TimeHelper,
private val configManager: ConfigManager,
private val eventRepository: SessionEventRepository,
private val generalConsentTextHelper: GeneralConsentTextHelper,
private val parentalConsentTextHelper: ParentalConsentTextHelper,
@ExternalScope private val externalScope: CoroutineScope,
) : ViewModel() {

private val startConsentEventTime = timeHelper.now()

private lateinit var generalConsentTextHelper: GeneralConsentTextHelper
private lateinit var parentalConsentTextHelper: ParentalConsentTextHelper

val viewState: LiveData<ConsentViewState>
get() = _viewState
private val _viewState = MutableLiveData(ConsentViewState())
Expand All @@ -53,6 +55,11 @@ internal class ConsentViewModel @Inject constructor(
get() = _returnConsentResult
private val _returnConsentResult = MutableLiveData<LiveDataEventWithContent<Serializable>>()

fun init(textHelperFactory: ConsentTextHelperFactory) {
generalConsentTextHelper = textHelperFactory.createGeneral()
parentalConsentTextHelper = textHelperFactory.createParental()
}

fun loadConfiguration(consentType: ConsentType) {
viewModelScope.launch {
val projectConfig = configManager.getProjectConfiguration()
Expand Down Expand Up @@ -89,7 +96,7 @@ internal class ConsentViewModel @Inject constructor(
private fun mapConfigToViewState(
projectConfig: ProjectConfiguration,
consentType: ConsentType,
selectedTabIndex: Int
selectedTabIndex: Int,
): ConsentViewState {
val allowParentalConsent = projectConfig.consent.allowParentalConsent

Expand All @@ -108,7 +115,7 @@ internal class ConsentViewModel @Inject constructor(

private fun saveConsentEvent(
currentConsentTab: ConsentTab,
result: ConsentEvent.ConsentPayload.Result
result: ConsentEvent.ConsentPayload.Result,
) = externalScope.launch {
eventRepository.addOrUpdateEvent(ConsentEvent(
startConsentEventTime,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.simprints.feature.consent.screens.consent.helpers

import android.content.Context
import dagger.hilt.android.qualifiers.ActivityContext
import javax.inject.Inject

/**
* Factory must be injected into the hilt entry point to receive the correct
* activity context which in turn will be passed to the text helpers.
*/
internal class ConsentTextHelperFactory @Inject constructor(
@ActivityContext private val context: Context,
) {

fun createGeneral() = GeneralConsentTextHelper(context)
fun createParental() = ParentalConsentTextHelper(context)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ import com.simprints.feature.consent.ConsentType
import com.simprints.infra.config.store.models.ConsentConfiguration
import com.simprints.infra.config.store.models.GeneralConfiguration
import com.simprints.infra.resources.R
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject

internal class GeneralConsentTextHelper @Inject constructor(
@ApplicationContext val context: Context,
internal class GeneralConsentTextHelper(
private val context: Context,
) {
// TODO All the `getString(id).format(arg,arg)` calls should be `getString(id,arg,arg)` one strings are fixed

Expand Down Expand Up @@ -116,3 +114,4 @@ internal class GeneralConsentTextHelper @Inject constructor(
GeneralConfiguration.Modality.FINGERPRINT -> context.getString(R.string.consent_biometrics_access_fingerprint)
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ import com.simprints.feature.consent.ConsentType
import com.simprints.infra.config.store.models.ConsentConfiguration
import com.simprints.infra.config.store.models.GeneralConfiguration.Modality
import com.simprints.infra.resources.R
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dagger.hilt.android.qualifiers.ActivityContext
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject

internal class ParentalConsentTextHelper @Inject constructor(
@ApplicationContext val context: Context
internal class ParentalConsentTextHelper(
private val context: Context
) {
// TODO All the `getString(id).format(arg,arg)` calls should be `getString(id,arg,arg)` one strings are fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.simprints.core.tools.time.TimeHelper
import com.simprints.core.tools.time.Timestamp
import com.simprints.feature.consent.ConsentResult
import com.simprints.feature.consent.ConsentType
import com.simprints.feature.consent.screens.consent.helpers.ConsentTextHelperFactory
import com.simprints.feature.consent.screens.consent.helpers.GeneralConsentTextHelper
import com.simprints.feature.consent.screens.consent.helpers.ParentalConsentTextHelper
import com.simprints.feature.exitform.ExitFormResult
Expand Down Expand Up @@ -43,6 +44,9 @@ class ConsentViewModelTest {
@MockK
private lateinit var timeHelper: TimeHelper

@MockK
private lateinit var consentTextHelperFactory: ConsentTextHelperFactory

@MockK
private lateinit var generalConsentTextHelper: GeneralConsentTextHelper

Expand All @@ -69,6 +73,9 @@ class ConsentViewModelTest {
coEvery { configManager.getProjectConfiguration() } returns projectConfig
every { projectConfig.consent } returns mockk()

every { consentTextHelperFactory.createGeneral() } returns generalConsentTextHelper
every { consentTextHelperFactory.createParental() } returns parentalConsentTextHelper

every { timeHelper.now() } returns TIMESTAMP
every { generalConsentTextHelper.assembleText(any(), any(), any()) } returns GENERAL_CONSENT
every { parentalConsentTextHelper.assembleText(any(), any(), any()) } returns PARENTAL_CONSENT
Expand All @@ -77,10 +84,9 @@ class ConsentViewModelTest {
timeHelper,
configManager,
eventRepository,
generalConsentTextHelper,
parentalConsentTextHelper,
CoroutineScope(testCoroutineRule.testCoroutineDispatcher)
)
vm.init(consentTextHelperFactory)
}

@Test
Expand Down Expand Up @@ -210,6 +216,7 @@ class ConsentViewModelTest {
}

companion object {

private val TIMESTAMP = Timestamp(1L)
private const val GENERAL_CONSENT = "General consent"
private const val PARENTAL_CONSENT = "Parental consent"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ internal class SettingsViewModel @Inject constructor(

fun updateLanguagePreference(language: String) {
viewModelScope.launch {
configManager.updateDeviceConfiguration { it.apply { it.language = language } }
configManager.updateDeviceConfiguration { config -> config.also { it.language = language } }
_languagePreference.postValue(language)
Simber.tag(LoggingConstants.CrashReportTag.SETTINGS.name).i("Language set to $language")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ package com.simprints.feature.selectagegroup.screen

import com.simprints.infra.config.store.models.AgeGroup

internal data class AgeGroupDisplayModel(val displayString: String, val range: AgeGroup)
internal data class AgeGroupDisplayModel(
val displayString: String,
val range: AgeGroup,
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import android.content.Context
import com.simprints.infra.config.store.ConfigRepository
import com.simprints.infra.config.store.models.AgeGroup
import com.simprints.infra.config.store.models.sortedUniqueAgeGroups
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import com.simprints.infra.resources.R as IDR

internal class BuildAgeGroupsDescriptionUseCase @Inject constructor(
internal class BuildAgeGroupsDescriptionUseCase(
private val configurationRepo: ConfigRepository,
@ApplicationContext private val context: Context,
private val context: Context,
) {

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.simprints.feature.selectagegroup.screen

import android.content.Context
import com.simprints.infra.config.store.ConfigRepository
import dagger.hilt.android.qualifiers.ActivityContext
import javax.inject.Inject

internal class BuildAgeGroupsDescriptionUseCaseFactory @Inject constructor(
private val configurationRepo: ConfigRepository,
@ActivityContext private val context: Context,
) {
fun create() = BuildAgeGroupsDescriptionUseCase(configurationRepo, context)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,20 @@ import com.simprints.infra.uibase.navigation.handleResult
import com.simprints.infra.uibase.navigation.navigateSafely
import com.simprints.infra.uibase.viewbinding.viewBinding
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject

@AndroidEntryPoint
internal class SelectSubjectAgeGroupFragment : Fragment(R.layout.fragment_age_group_selection) {

private val viewModel: SelectSubjectAgeGroupViewModel by viewModels()
private val binding by viewBinding(FragmentAgeGroupSelectionBinding::bind)

@Inject
internal lateinit var descriptionUseCaseFactory: BuildAgeGroupsDescriptionUseCaseFactory

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.init(descriptionUseCaseFactory)

viewModel.ageGroups.observe(viewLifecycleOwner) { ageGroupsList ->
fillRecyclerView(ageGroupsList)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ import javax.inject.Inject
internal class SelectSubjectAgeGroupViewModel @Inject constructor(
private val timeHelper: TimeHelper,
private val eventRepository: SessionEventRepository,
private val buildAgeGroups: BuildAgeGroupsDescriptionUseCase,
private val configurationRepo: ConfigRepository,
@ExternalScope private val externalScope: CoroutineScope,
) : ViewModel() {

private lateinit var buildAgeGroupDescription: BuildAgeGroupsDescriptionUseCase

val finish: LiveData<LiveDataEventWithContent<AgeGroup>>
get() = _finish
private var _finish = MutableLiveData<LiveDataEventWithContent<AgeGroup>>()
Expand All @@ -47,9 +48,13 @@ internal class SelectSubjectAgeGroupViewModel @Inject constructor(
private val _showExitForm =
MutableLiveData<LiveDataEventWithContent<ExitFormConfigurationBuilder>>()

fun init(factory: BuildAgeGroupsDescriptionUseCaseFactory) {
buildAgeGroupDescription = factory.create()
}

fun start() = viewModelScope.launch {
startTime = timeHelper.now()
val ageGroups = buildAgeGroups()
val ageGroups = buildAgeGroupDescription()
// notify the adapter
_ageGroupsDisplayModel.value = ageGroups
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.simprints.infra.resources.R
import com.simprints.testtools.common.coroutines.TestCoroutineRule
import io.mockk.MockKAnnotations
import io.mockk.coEvery
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.impl.annotations.RelaxedMockK
import kotlinx.coroutines.CoroutineScope
Expand All @@ -33,6 +34,9 @@ class SelectSubjectAgeGroupViewModelTest {
@MockK
private lateinit var buildAgeGroups: BuildAgeGroupsDescriptionUseCase

@MockK
private lateinit var buildAgeGroupsDescriptionUseCaseFactory: BuildAgeGroupsDescriptionUseCaseFactory

@RelaxedMockK
private lateinit var configurationRepo: ConfigRepository

Expand All @@ -52,13 +56,15 @@ class SelectSubjectAgeGroupViewModelTest {
MockKAnnotations.init(this)
coEvery { buildAgeGroups() } returns ageGroupViewModels

every { buildAgeGroupsDescriptionUseCaseFactory.create() } returns buildAgeGroups

viewModel = SelectSubjectAgeGroupViewModel(
timeHelper,
eventRepository,
buildAgeGroups,
configurationRepo,
CoroutineScope(testCoroutineRule.testCoroutineDispatcher)
)
viewModel.init(buildAgeGroupsDescriptionUseCaseFactory)
}

@Test
Expand Down Expand Up @@ -92,6 +98,7 @@ class SelectSubjectAgeGroupViewModelTest {
Truth.assertThat(result.titleRes).isEqualTo(R.string.exit_form_title_fingerprinting)
Truth.assertThat(result.backButtonRes).isEqualTo(R.string.exit_form_continue_fingerprints_button)
}

@Test
fun `test onBackPressed face modality`() = runTest {
coEvery { configurationRepo.getProjectConfiguration().general.modalities } returns listOf(
Expand All @@ -102,8 +109,9 @@ class SelectSubjectAgeGroupViewModelTest {

// Assert that the titleRes and backButtonRes are equal to the face modality
Truth.assertThat(result.titleRes).isEqualTo(R.string.exit_form_title_face)
Truth.assertThat( result.backButtonRes).isEqualTo(R.string.exit_form_continue_face_button)
Truth.assertThat(result.backButtonRes).isEqualTo(R.string.exit_form_continue_face_button)
}

@Test
fun `test onBackPressed multiple modalities`() = runTest {
coEvery { configurationRepo.getProjectConfiguration().general.modalities } returns listOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.simprints.core.tools.utils
import android.content.Context
import android.content.SharedPreferences
import android.content.res.Configuration
import androidx.core.content.edit
import com.simprints.core.ExcludedFromGeneratedTestCoverageReports
import java.util.*

Expand All @@ -16,11 +17,9 @@ object LanguageHelper {

lateinit var prefs: SharedPreferences
var language: String
get() {
return prefs.getString(SHARED_PREFS_LANGUAGE_KEY, SHARED_PREFS_LANGUAGE_DEFAULT)!!
}
get() = prefs.getString(SHARED_PREFS_LANGUAGE_KEY, SHARED_PREFS_LANGUAGE_DEFAULT)!!
set(value) {
prefs.edit().putString(SHARED_PREFS_LANGUAGE_KEY, value).apply()
prefs.edit(commit = true) { putString(SHARED_PREFS_LANGUAGE_KEY, value) }
}

fun init(ctx: Context) {
Expand Down