Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Main | Performance improvements #3586

Open
wants to merge 131 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
131 commits
Select commit Hold shift + click to select a range
deb1cfd
Test single transaction save for questionnaires
LZRS Aug 16, 2024
8129afd
Caching questionnaires and their SM
aurangzaibumer Aug 23, 2024
e9221d1
spotless ran
aurangzaibumer Aug 23, 2024
22a908f
Fetch search results in batches for when loading all
LZRS Aug 20, 2024
5022fa8
Fix infinite loop for mocks with FhirEngine#search in tests
LZRS Aug 20, 2024
6ee690d
[WIP] FhirEngine search integration tests
LZRS Aug 26, 2024
ae166a4
spotless ran
aurangzaibumer Aug 28, 2024
79f664d
updated tests
aurangzaibumer Sep 2, 2024
76a4113
Merge branch 'main' into caching_resources
aurangzaibumer Sep 2, 2024
a06ca8c
Merge branch 'main' into caching_resources
dubdabasoduba Sep 2, 2024
c6be824
WIP tests updated
aurangzaibumer Sep 5, 2024
3e307d5
Merge remote-tracking branch 'origin/caching_resources' into caching_…
aurangzaibumer Sep 5, 2024
2390a89
Merge branch 'main' into caching_resources
aurangzaibumer Sep 6, 2024
0381c5a
resolved feedback
aurangzaibumer Sep 7, 2024
45e135f
spotess ran
aurangzaibumer Sep 7, 2024
0171ca2
Merge branch 'main' into caching_resources
aurangzaibumer Sep 7, 2024
266dd65
Upgrade FHIR SDK depenencies ⬆️
ndegwamartin Jul 31, 2024
6522d71
Upragde SDC library
ndegwamartin Aug 8, 2024
241e03e
Replace JWT token parser library
ndegwamartin Aug 9, 2024
acf6d23
Fix CQL Content Test
ndegwamartin Aug 9, 2024
b6b45ff
Fix unit tests ✅
ndegwamartin Aug 13, 2024
8638f22
Refactor to remove Dispatch Provider
ndegwamartin Aug 13, 2024
da63a1b
Fix unit test ✅
ndegwamartin Aug 16, 2024
a520fea
Refactor Knowledge Manager Resources Persistance
ndegwamartin Aug 19, 2024
7eb0fde
Refactor CQL Content tests
ndegwamartin Aug 20, 2024
0ad5ada
Fix AppSettingModel unit tests ✅
ndegwamartin Aug 20, 2024
783be6d
Refactor Cancel previous worflow to use native commands
ndegwamartin Aug 20, 2024
24c5b2d
Upgrade CI API level to 34
ndegwamartin Aug 20, 2024
5074794
Clean up Translations
ndegwamartin Aug 21, 2024
54b08f7
Fix measure reporting
ndegwamartin Aug 28, 2024
c01d519
Fix Workflow Configuration
ndegwamartin Aug 28, 2024
8400b5f
Fix QuestionnaireViewModel unit tests ✅
ndegwamartin Aug 28, 2024
b6770ed
Clean up WorkManager after running unit tests
ndegwamartin Aug 29, 2024
172819a
Remove skyscreamer test dependency
ndegwamartin Aug 29, 2024
e5ee043
Fix build 💚
ndegwamartin Aug 29, 2024
5746a3c
Clean up gradle dependencies configuration
ndegwamartin Sep 2, 2024
aecff74
Move measure reporting evaluation to BG thread
ndegwamartin Sep 2, 2024
d2cdd22
Fix MeasureReportRepositoryTest
ndegwamartin Sep 2, 2024
1107d30
Fix MeasureReportRepositoryTest
ndegwamartin Sep 2, 2024
b8f213d
Fix MeasureReportViewModel unit tests ✅
ndegwamartin Sep 3, 2024
d95173f
Fix Measure Reporting
ndegwamartin Sep 9, 2024
638fd57
Merge remote-tracking branch 'origin/main' into performance-improvements
LZRS Sep 10, 2024
2806bdc
Merge remote-tracking branch 'origin/migrate-deps' into performance-i…
LZRS Sep 10, 2024
22e3ce3
Migrate Engine and Workflow libraries
ndegwamartin Sep 10, 2024
3953377
Merge remote-tracking branch 'origin/migrate-deps' into performance-i…
LZRS Sep 10, 2024
9027b74
Merge remote-tracking branch 'origin/caching_resources' into performa…
LZRS Sep 10, 2024
6756c08
Merge remote-tracking branch 'origin/test_save_with_transaction' into…
LZRS Sep 11, 2024
96dd00e
Refactor register filter with REL tags
ellykits Sep 11, 2024
055a1be
Update default pageSize to 15
ellykits Sep 11, 2024
960176c
Fix loading locations on map
ellykits Sep 11, 2024
c13157c
Refactor data structure used on base resource search results
ellykits Sep 12, 2024
06d81a9
Merge branch 'main' into fix-register-filters
dubdabasoduba Sep 12, 2024
3f4c49e
Merge branch 'fix-register-filters' of github.com:opensrp/fhircore in…
ellykits Sep 12, 2024
566b65d
Process saveCredentials in the background
qiarie Sep 12, 2024
6c32e62
Refactor code
ellykits Sep 13, 2024
6ffbca0
Delete unnecessary code
ellykits Sep 13, 2024
3eeb9aa
Refactor retrieving related resources
ellykits Sep 15, 2024
fb0a037
Merge branch 'main' into fix-register-filters
ellykits Sep 15, 2024
94c13ff
Optimize data structures and perform parallel processing
ellykits Sep 15, 2024
20980f7
Use recent version of rules engine library
ellykits Sep 15, 2024
b01b59c
Refactor implementation for decoding image resources to bitmap
ellykits Sep 15, 2024
b232cce
Fix related resource count on register
ellykits Sep 16, 2024
398c987
Fix loading related resources
ellykits Sep 16, 2024
aca51d7
Batch related resource queries
ellykits Sep 16, 2024
2e3e48c
Map resources to RepositoryResourceData with async map
ellykits Sep 16, 2024
2eb9c85
Make infinite scroll the default register behavior
ellykits Sep 16, 2024
b3f838a
Disable automatic intialization of emoji2
ellykits Sep 16, 2024
77d1662
Run spotlessApply
ellykits Sep 17, 2024
513c805
Update tests for displaying images (#3506)
Lentumunai-Mark Sep 17, 2024
8546693
Refactor navigation to GeowidgetLauncher workflow
ellykits Sep 17, 2024
ba00c5e
Merge remote-tracking branch 'origin/refactor-login-save-credentials'…
LZRS Sep 18, 2024
81e8b7d
Use dipatcher IO to handle questionnaire submission
LZRS Sep 18, 2024
383be26
Merge remote-tracking branch 'origin/fix-register-filters' into perfo…
LZRS Sep 18, 2024
639195f
Merge remote-tracking branch 'origin/handle-submission-perf-improveme…
LZRS Sep 18, 2024
bd68521
Hotfix space_asterisk
LZRS Sep 18, 2024
61a2abb
Upgrade engine to v1.0.0-preview14.1-SNAPSHOT
LZRS Sep 18, 2024
27c5f64
Update infiniteScroll to not be default
qiarie Sep 18, 2024
39c1db6
Update sdk versions
LZRS Sep 20, 2024
aad8b61
Update integration Faker to fix error
LZRS Sep 20, 2024
ef67328
Revert upgrade on workflow and knowledge libs
LZRS Sep 20, 2024
c04024f
Upgrade FHIR SDK depenencies ⬆️
ndegwamartin Jul 31, 2024
e2da55e
Upragde SDC library
ndegwamartin Aug 8, 2024
f6bbada
Replace JWT token parser library
ndegwamartin Aug 9, 2024
64c6297
Fix CQL Content Test
ndegwamartin Aug 9, 2024
7e616ac
Fix unit tests ✅
ndegwamartin Aug 13, 2024
4f3c74c
Refactor to remove Dispatch Provider
ndegwamartin Aug 13, 2024
6d35db9
Fix unit test ✅
ndegwamartin Aug 16, 2024
21420ae
Refactor Knowledge Manager Resources Persistance
ndegwamartin Aug 19, 2024
6920620
Refactor CQL Content tests
ndegwamartin Aug 20, 2024
fdc9097
Fix AppSettingModel unit tests ✅
ndegwamartin Aug 20, 2024
ed1dee7
Refactor Cancel previous worflow to use native commands
ndegwamartin Aug 20, 2024
35f22b4
Upgrade CI API level to 34
ndegwamartin Aug 20, 2024
9d83a1d
Clean up Translations
ndegwamartin Aug 21, 2024
8aa5740
Fix measure reporting
ndegwamartin Aug 28, 2024
5074b5a
Fix Workflow Configuration
ndegwamartin Aug 28, 2024
e603cda
Fix QuestionnaireViewModel unit tests ✅
ndegwamartin Aug 28, 2024
25df56e
Clean up WorkManager after running unit tests
ndegwamartin Aug 29, 2024
9b9f922
Remove skyscreamer test dependency
ndegwamartin Aug 29, 2024
2cfe37c
Fix build 💚
ndegwamartin Aug 29, 2024
ff1e3c6
Clean up gradle dependencies configuration
ndegwamartin Sep 2, 2024
9a96a82
Move measure reporting evaluation to BG thread
ndegwamartin Sep 2, 2024
8ff7951
Fix MeasureReportRepositoryTest
ndegwamartin Sep 2, 2024
6c56419
Fix MeasureReportRepositoryTest
ndegwamartin Sep 2, 2024
4057e11
Fix MeasureReportViewModel unit tests ✅
ndegwamartin Sep 3, 2024
74f754d
Fix Measure Reporting
ndegwamartin Sep 9, 2024
5e6b203
Migrate Engine and Workflow libraries
ndegwamartin Sep 10, 2024
a1ef8cd
Update Workflow library
ndegwamartin Sep 11, 2024
ae6708d
Fix evaluate Population Measure
ndegwamartin Sep 11, 2024
afb4ade
Update SDC snapshot to 14.1
ndegwamartin Sep 13, 2024
3d7b2e2
Remove unrecommended forced portrait format
ndegwamartin Sep 13, 2024
affa880
Refactor from using deprecated KnowledgeManager methods loadResources
ndegwamartin Sep 13, 2024
37a462b
Clean up TOML catalog file
ndegwamartin Sep 16, 2024
d3250b2
Revert Knowledge Manager and Workflow Library Upgrades
ndegwamartin Sep 17, 2024
9774be9
Display symbol instead of unicode
FikriMilano Sep 18, 2024
c9d2bde
Refactor usage of FHIR JSONParser to support concurrency
ndegwamartin Sep 18, 2024
d2ffbb5
Update FHIR SDK library versions
ndegwamartin Sep 18, 2024
234c7d6
Geowidget configuration
ndegwamartin Sep 18, 2024
0a72665
Fix build 💚
ndegwamartin Sep 18, 2024
7f4da95
SDK Engine to RC3
ndegwamartin Sep 20, 2024
f694d0b
Fix build
ndegwamartin Sep 20, 2024
e019834
Merge remote-tracking branch 'origin/migrate-deps' into performance-i…
LZRS Sep 20, 2024
82aa807
Merge remote-tracking branch 'origin/migrate-deps' into performance-i…
LZRS Sep 20, 2024
8ad1cbd
Fix failing ci tests
LZRS Sep 20, 2024
7c51716
Update data-capture lib to v1.1.0-preview14-rc2-SNAPSHOT
LZRS Sep 20, 2024
441e792
Merge remote-tracking branch 'origin/main' into performance-improvements
LZRS Nov 4, 2024
ba76e1f
Merge branch 'main' into performance-improvements
dubdabasoduba Nov 4, 2024
2eb0b8c
Fix errors in tests
LZRS Nov 4, 2024
692380d
🐛 Readd the eusm mg and bi flavour
dubdabasoduba Nov 5, 2024
6993289
🔥 Remove unnecessary files
dubdabasoduba Nov 5, 2024
bd7b3a5
Merge remote-tracking branch 'refs/remotes/origin/performance-improve…
dubdabasoduba Nov 5, 2024
b888647
🍻 Removing double flavour defination
dubdabasoduba Nov 5, 2024
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
2 changes: 1 addition & 1 deletion android/buildSrc/src/main/kotlin/BuildConfigs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ object BuildConfigs {
const val compileSdk = 34
const val targetSdk = 34
const val versionCode = 11
const val versionName = "2.0.0"
const val versionName = "2.0.0.2"
const val applicationId = "org.smartregister.opensrp"
const val jvmToolchain = 17
const val kotlinCompilerExtensionVersion = "1.5.8"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import java.util.Base64
import javax.inject.Inject
import javax.inject.Singleton
import javax.net.ssl.SSLHandshakeException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.smartregister.fhircore.engine.configuration.app.ConfigService
import org.smartregister.fhircore.engine.data.remote.auth.OAuthService
Expand Down Expand Up @@ -215,8 +217,11 @@ constructor(
addAccountExplicitly(newAccount, oAuthResponse.refreshToken, null)
setAuthToken(newAccount, AUTH_TOKEN_TYPE, oAuthResponse.accessToken)
}

// Save credentials
secureSharedPreference.saveCredentials(username, password)
CoroutineScope(dispatcherProvider.io()).launch {
secureSharedPreference.saveCredentials(username, password)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 2021-2024 Ona Systems, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.smartregister.fhircore.engine.datastore

import androidx.collection.LruCache
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.hl7.fhir.r4.model.Resource
import timber.log.Timber

object ContentCache {
private val maxMemory: Int = (Runtime.getRuntime().maxMemory() / 1024).toInt()
private val cacheSize: Int = maxMemory / 8
private val cache = LruCache<String, Resource>(cacheSize)

@JvmStatic
suspend fun saveResource(resourceId: String, resource: Resource) =
withContext(Dispatchers.IO) {
cache.put("${resource::class.simpleName}/$resourceId", resource)
Timber.i("ContentCache:saveResource: $resourceId")
}

@JvmStatic
fun getResource(resourceId: String): Resource? {
return cache[resourceId]?.also { Timber.i("ContentCache:getResource: $resourceId") }
}

suspend fun invalidate() =
withContext(Dispatchers.IO) {
cache.evictAll()
Timber.i("ContentCache: clearing cache")

Check warning on line 45 in android/engine/src/main/java/org/smartregister/fhircore/engine/datastore/ContentCache.kt

View check run for this annotation

Codecov / codecov/patch

android/engine/src/main/java/org/smartregister/fhircore/engine/datastore/ContentCache.kt#L44-L45

Added lines #L44 - L45 were not covered by tests
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import org.smartregister.fhircore.engine.R
import org.smartregister.fhircore.engine.configuration.QuestionnaireConfig
import org.smartregister.fhircore.engine.configuration.event.EventType
import org.smartregister.fhircore.engine.data.local.DefaultRepository
import org.smartregister.fhircore.engine.datastore.ContentCache
import org.smartregister.fhircore.engine.util.extension.addResourceParameter
import org.smartregister.fhircore.engine.util.extension.asReference
import org.smartregister.fhircore.engine.util.extension.batchedSearch
Expand Down Expand Up @@ -214,8 +215,16 @@ constructor(
}
source.setParameter(Task.SP_PERIOD, period)
source.setParameter(ActivityDefinition.SP_VERSION, IntegerType(index))

val structureMap = fhirEngine.get<StructureMap>(IdType(action.transform).idPart)
val structureMapId = IdType(action.transform).idPart
val structureMap =
ContentCache.getResource(ResourceType.StructureMap.name + "/" + structureMapId)?.let {
it as StructureMap
}
?: run {
fhirEngine.get<StructureMap>(structureMapId).also {
ContentCache.saveResource(structureMapId, it)
}
}
structureMapUtilities.transform(
transformSupportServices.simpleWorkerContext,
source,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.RequestBody.Companion.toRequestBody
import org.apache.commons.lang3.StringUtils
import org.hl7.fhir.r4.model.Binary
import org.hl7.fhir.r4.model.Bundle
import org.hl7.fhir.r4.model.Composition
import org.hl7.fhir.r4.model.ResourceType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ import androidx.activity.viewModels
import androidx.annotation.VisibleForTesting
import androidx.compose.material.ExperimentalMaterialApi
import androidx.core.os.bundleOf
import androidx.lifecycle.viewModelScope
import androidx.work.WorkManager
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
import kotlinx.coroutines.launch
import org.smartregister.fhircore.engine.data.remote.shared.TokenAuthenticator
import org.smartregister.fhircore.engine.datastore.ContentCache
import org.smartregister.fhircore.engine.p2p.dao.P2PReceiverTransferDao
import org.smartregister.fhircore.engine.p2p.dao.P2PSenderTransferDao
import org.smartregister.fhircore.engine.sync.AppSyncWorker
Expand Down Expand Up @@ -84,7 +87,7 @@ open class LoginActivity : BaseMultiLanguageActivity() {
navigateToPinLogin(launchSetup = false)
}
}

viewModelScope.launch { ContentCache.invalidate() }
navigateToHome.observe(loginActivity) { launchHomeScreen ->
if (launchHomeScreen) {
downloadNowWorkflowConfigs()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import org.hl7.fhir.r4.model.QuestionnaireResponse.QuestionnaireResponseItemComp
import org.hl7.fhir.r4.model.RelatedPerson
import org.hl7.fhir.r4.model.Resource
import org.hl7.fhir.r4.model.ResourceType
import org.hl7.fhir.r4.model.StructureMap
import org.smartregister.fhircore.engine.BuildConfig
import org.smartregister.fhircore.engine.configuration.ConfigType
import org.smartregister.fhircore.engine.configuration.ConfigurationRegistry
Expand All @@ -69,6 +70,7 @@ import org.smartregister.fhircore.engine.configuration.QuestionnaireConfig
import org.smartregister.fhircore.engine.configuration.app.ApplicationConfiguration
import org.smartregister.fhircore.engine.configuration.app.CodingSystemUsage
import org.smartregister.fhircore.engine.data.local.DefaultRepository
import org.smartregister.fhircore.engine.datastore.ContentCache
import org.smartregister.fhircore.engine.domain.model.ActionParameter
import org.smartregister.fhircore.engine.domain.model.ActionParameterType
import org.smartregister.fhircore.engine.domain.model.isEditable
Expand Down Expand Up @@ -147,7 +149,21 @@ constructor(
questionnaireConfig: QuestionnaireConfig,
): Questionnaire? {
if (questionnaireConfig.id.isEmpty() || questionnaireConfig.id.isBlank()) return null
return defaultRepository.loadResource<Questionnaire>(questionnaireConfig.id)
var result =
ContentCache.getResource(ResourceType.Questionnaire.name + "/" + questionnaireConfig.id)
?.copy()
if (result == null) {
result =
defaultRepository.loadResource<Questionnaire>(questionnaireConfig.id)?.also { questionnaire,
->
ContentCache.saveResource(
questionnaireConfig.id,
questionnaire.copy(),
)
}
}

return result as Questionnaire
}

/**
Expand Down Expand Up @@ -196,63 +212,67 @@ constructor(
context = context,
)

saveExtractedResources(
bundle = bundle,
questionnaire = questionnaire,
questionnaireConfig = questionnaireConfig,
questionnaireResponse = currentQuestionnaireResponse,
context = context,
)

updateResourcesLastUpdatedProperty(actionParameters)
val doSaveOperations: suspend () -> Unit = {
saveExtractedResources(
bundle = bundle,
questionnaire = questionnaire,
questionnaireConfig = questionnaireConfig,
questionnaireResponse = currentQuestionnaireResponse,
context = context,
)

// Important to load subject resource to retrieve ID (as reference) correctly
val subjectIdType: IdType? =
if (currentQuestionnaireResponse.subject.reference.isNullOrEmpty()) {
null
} else {
IdType(currentQuestionnaireResponse.subject.reference)
}
updateResourcesLastUpdatedProperty(actionParameters)

if (subjectIdType != null) {
val subject =
loadResource(
ResourceType.valueOf(subjectIdType.resourceType),
subjectIdType.idPart,
)
// Important to load subject resource to retrieve ID (as reference) correctly
val subjectIdType: IdType? =
if (currentQuestionnaireResponse.subject.reference.isNullOrEmpty()) {
null
} else {
IdType(currentQuestionnaireResponse.subject.reference)
}

if (subject != null && !questionnaireConfig.isReadOnly()) {
val newBundle = bundle.copyBundle(currentQuestionnaireResponse)
if (subjectIdType != null) {
val subject =
loadResource(
ResourceType.valueOf(subjectIdType.resourceType),
subjectIdType.idPart,
)

val extractedResources = newBundle.entry.map { it.resource }
validateWithFhirValidator(*extractedResources.toTypedArray())
if (subject != null && !questionnaireConfig.isReadOnly()) {
val newBundle = bundle.copyBundle(currentQuestionnaireResponse)

generateCarePlan(
subject = subject,
bundle = newBundle,
questionnaireConfig = questionnaireConfig,
)
val extractedResources = newBundle.entry.map { it.resource }
validateWithFhirValidator(*extractedResources.toTypedArray())

withContext(dispatcherProvider.io()) {
executeCql(
generateCarePlan(
subject = subject,
bundle = newBundle,
questionnaire = questionnaire,
questionnaireConfig = questionnaireConfig,
)
}

fhirCarePlanGenerator.conditionallyUpdateResourceStatus(
questionnaireConfig = questionnaireConfig,
subject = subject,
bundle = newBundle,
)
withContext(dispatcherProvider.io()) {
executeCql(
subject = subject,
bundle = newBundle,
questionnaire = questionnaire,
questionnaireConfig = questionnaireConfig,
)
}

fhirCarePlanGenerator.conditionallyUpdateResourceStatus(
questionnaireConfig = questionnaireConfig,
subject = subject,
bundle = newBundle,
)
}
}
}

softDeleteResources(questionnaireConfig)
softDeleteResources(questionnaireConfig)

retireUsedQuestionnaireUniqueId(questionnaireConfig, currentQuestionnaireResponse)
}

retireUsedQuestionnaireUniqueId(questionnaireConfig, currentQuestionnaireResponse)
defaultRepository.fhirEngine.withTransaction { doSaveOperations.invoke() }

val idTypes =
bundle.entry?.map { IdType(it.resource.resourceType.name, it.resource.logicalId) }
Expand Down Expand Up @@ -637,8 +657,15 @@ constructor(
StructureMapExtractionContext(
transformSupportServices = transformSupportServices,
structureMapProvider = { structureMapUrl: String?, _: IWorkerContext ->
structureMapUrl?.substringAfterLast("/")?.let {
defaultRepository.loadResource(it)
structureMapUrl?.substringAfterLast("/")?.let { smID ->
ContentCache.getResource(ResourceType.StructureMap.name + "/" + smID)?.let {
it as StructureMap
}
?: run {
defaultRepository.loadResource<StructureMap>(smID)?.also {
ContentCache.saveResource(smID, it)
}
}
}
},
),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright 2021-2024 Ona Systems, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.smartregister.fhircore.quest

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
import org.hl7.fhir.r4.model.Questionnaire
import org.hl7.fhir.r4.model.Resource
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Before
import org.junit.Test
import org.smartregister.fhircore.engine.datastore.ContentCache

@OptIn(ExperimentalCoroutinesApi::class)
class ContentCacheTest {

private val testDispatcher = StandardTestDispatcher()
private val resourceId = "123"
private val mockResource: Resource = Questionnaire()

@Before
fun setUp() {
Dispatchers.setMain(testDispatcher)
}

@After
fun tearDown() {
Dispatchers.resetMain()
}

@Test
fun `saveResource should store resource in cache`() = runTest {
ContentCache.saveResource(resourceId, mockResource)
advanceUntilIdle() // Ensure coroutine has finished

val cachedResource = ContentCache.getResource("${mockResource::class.simpleName}/$resourceId")
assertNotNull(cachedResource)
assertEquals(mockResource, cachedResource)
}

@Test
fun `getResource should return the correct resource from cache`() = runTest {
ContentCache.saveResource(resourceId, mockResource)
advanceUntilIdle() // Ensure coroutine has finished

val result = ContentCache.getResource("${mockResource::class.simpleName}/$resourceId")
assertEquals(mockResource, result)
}

@Test
fun `getResource should return null if resource does not exist`() = runTest {
val result = ContentCache.getResource("non_existing_id")
assertNull(result)
}

@Test
fun `invalidate should clear all resources from cache`() = runTest {
ContentCache.saveResource(resourceId, mockResource)
advanceUntilIdle() // Ensure coroutine has finished

ContentCache.invalidate()
advanceUntilIdle() // Ensure coroutine has finished

val result = ContentCache.getResource("${mockResource::class.simpleName}/$resourceId")
assertNull(result)
}
}
Loading
Loading