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

Basic test for lazy loading Case Lists #1513

Merged
merged 4 commits into from
Dec 20, 2023
Merged
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 @@ -4,16 +4,18 @@
import org.commcare.formplayer.engine.ClasspathFileRoot;
import org.commcare.formplayer.util.PrototypeUtils;
import org.javarosa.core.model.utils.DateUtils;
import org.javarosa.core.reference.ReferenceHandler;
import org.javarosa.core.reference.ReferenceManager;
import org.javarosa.core.services.locale.Localization;
import org.javarosa.core.services.locale.LocalizerManager;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;

/**
* Perform initialization of static utils.
*/
public class InitializeStaticsExtension implements BeforeEachCallback {
public class InitializeStaticsExtension implements BeforeEachCallback, AfterEachCallback {
@Override
public void beforeEach(ExtensionContext context) throws Exception {
LocalizerManager.setUseThreadLocalStrategy(true);
Expand All @@ -26,4 +28,10 @@ public void beforeEach(ExtensionContext context) throws Exception {
PrototypeUtils.setupThreadLocalPrototypes();
DateUtils.setTimezoneProvider(new MockTimezoneProvider());
}

@Override
public void afterEach(ExtensionContext context) throws Exception {
ReferenceHandler.clearInstance();
LocalizerManager.clearInstance();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class RestoreFactoryExtension(
private val domain: String,
private val asUser: String?,
var restorePath: String = "test_restore.xml"
) : BeforeAllCallback, BeforeEachCallback, AfterEachCallback {
) : BeforeEachCallback, AfterEachCallback {

lateinit var restoreFactory: RestoreFactory
private val sessionSelectionsCache: MutableSet<String> = HashSet()
Expand All @@ -58,11 +58,8 @@ class RestoreFactoryExtension(
}
}

override fun beforeAll(context: ExtensionContext) {
restoreFactory = SpringExtension.getApplicationContext(context).getBean(RestoreFactory::class.java)
}

override fun beforeEach(context: ExtensionContext) {
restoreFactory = SpringExtension.getApplicationContext(context).getBean(RestoreFactory::class.java)
reset()
restoreFactory.configure(username, domain, asUser, DjangoAuth("test"))
configureMock()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class StorageFactoryExtension(
private val appId: String,
private val asUser: String?,
private val asCaseId: String?
) : BeforeAllCallback, BeforeEachCallback, AfterEachCallback {
) : BeforeEachCallback, AfterEachCallback {

private lateinit var storageFactory: FormplayerStorageFactory

Expand All @@ -54,11 +54,8 @@ class StorageFactoryExtension(
}
}

override fun beforeAll(context: ExtensionContext) {
storageFactory = SpringExtension.getApplicationContext(context).getBean(FormplayerStorageFactory::class.java)
}

override fun beforeEach(context: ExtensionContext) {
storageFactory = SpringExtension.getApplicationContext(context).getBean(FormplayerStorageFactory::class.java)
storageFactory.configure(username, domain, appId, asUser, asCaseId)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,11 @@ class SessionNavigationRequest<out T : BaseResponseBean>(
sessionNavigationBean.selections = selections
return sessionNavigationBean
}

fun getNavigationBeanForPage(selections: Array<String>, offset : Int, casesPerPage : Int): SessionNavigationBean {
val sessionNavigationBean = getNavigationBean(selections)
sessionNavigationBean.offset = offset
sessionNavigationBean.casesPerPage = casesPerPage
return sessionNavigationBean
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package org.commcare.formplayer.tests

import org.commcare.formplayer.application.MenuController
import org.commcare.formplayer.beans.menus.BaseResponseBean
import org.commcare.formplayer.beans.menus.EntityListResponse
import org.commcare.formplayer.configuration.CacheConfiguration
import org.commcare.formplayer.junit.*
import org.commcare.formplayer.junit.Installer.Companion.getInstallReference
import org.commcare.formplayer.junit.request.SessionNavigationRequest
import org.commcare.formplayer.utils.TestContext
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.api.extension.RegisterExtension
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.context.annotation.Import
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.web.servlet.MockMvc

@WebMvcTest
@Import(MenuController::class)
@ContextConfiguration(classes = [TestContext::class, CacheConfiguration::class])
@ExtendWith(InitializeStaticsExtension::class)
class CaseListLazyLoadingTests {

companion object {
const val APP_NAME = "case_claim_with_multi_select"
}

@Autowired
private lateinit var mockMvc: MockMvc

@RegisterExtension
var restoreFactoryExt = RestoreFactoryExtension.builder()
.withUser("test").withDomain("test")
.withRestorePath("restores/caseclaim.xml")
.build()

@RegisterExtension
var storageExt = StorageFactoryExtension.builder()
.withUser("test").withDomain("test").build()


@Test
fun testLazyLoadingDetail_PaginatesAsNormal() {
val selections = arrayOf("5")
var response = navigate(selections, EntityListResponse::class.java, 0, 2)
var entitites = response.entities
assertEquals(response.pageCount, 4)
assertEquals(entitites.size, 2)

// Ensure both sort and non sort fields are populated
var singleEntity = entitites[1]
assertEquals(singleEntity.data[0], "Batman Begins")
assertEquals(singleEntity.data[1], "Batman Begins")
assertEquals(singleEntity.groupKey, "Batman Begins")

response = navigate(selections, EntityListResponse::class.java, 1, 3)
entitites = response.entities
assertEquals(response.pageCount, 3)
assertEquals(entitites.size, 3)
singleEntity = entitites[2]
assertEquals(singleEntity.data[0], "Rudolph")
assertEquals(singleEntity.data[1], "Rudolph")
assertEquals(singleEntity.groupKey, "Rudolph")
}

private fun <T : BaseResponseBean> navigate(
selections: Array<String>, responseClass: Class<T>, offset: Int, casesPerPage: Int
): T {
val installReference = getInstallReference(APP_NAME)
val request = SessionNavigationRequest(
mockMvc, responseClass, installReference
)
val bean = request.getNavigationBeanForPage(selections, offset, casesPerPage)
return request.requestWithBean(bean).bean()
}
}
47 changes: 43 additions & 4 deletions src/test/java/org/commcare/formplayer/tests/EndpointActionsTest.kt
Original file line number Diff line number Diff line change
@@ -1,23 +1,51 @@
package org.commcare.formplayer.tests

import org.commcare.formplayer.application.MenuController
import org.commcare.formplayer.beans.menus.BaseResponseBean
import org.commcare.formplayer.beans.menus.EntityListResponse
import org.junit.jupiter.api.Assertions.*
import org.commcare.formplayer.configuration.CacheConfiguration
import org.commcare.formplayer.junit.*
import org.commcare.formplayer.junit.request.SessionNavigationRequest
import org.commcare.formplayer.utils.TestContext
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNull
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.api.extension.RegisterExtension
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.context.annotation.Import
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.web.servlet.MockMvc

@WebMvcTest
class EndpointActionsTest : BaseTestClass() {
@Import(MenuController::class)
@ContextConfiguration(classes = [TestContext::class, CacheConfiguration::class])
@ExtendWith(InitializeStaticsExtension::class)
class EndpointActionsTest {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changes here are not related to PR and I end up doing it under a wrong assumption, but keeping the changes since it's still a good change to make.


companion object {
const val APP_NAME = "multi_select_case_list"
}

@Autowired
private lateinit var mockMvc: MockMvc

@RegisterExtension
var restoreFactoryExt = RestoreFactoryExtension.builder()
.withUser("test").withDomain("test")
.withRestorePath("test_restore.xml")
.build()

@RegisterExtension
var storageExt = StorageFactoryExtension.builder()
.withUser("test").withDomain("test").build()

@Test
fun testEndpointActionResponse() {
val selections = arrayOf("0", "1")
val entityListResponse: EntityListResponse = sessionNavigate(
val entityListResponse: EntityListResponse = navigate(
selections,
APP_NAME,
EntityListResponse::class.java
)
val endpoitnActionsResponse = entityListResponse.endpointActions
Expand All @@ -26,4 +54,15 @@ class EndpointActionsTest : BaseTestClass() {
assertEquals(true, endpoitnActionsResponse[0].isBackground)
assertNull(endpoitnActionsResponse[1], "Endpoint Action response for fields with no endpoint_action should be null")
}

private fun <T : BaseResponseBean> navigate(
selections: Array<String>, responseClass: Class<T>
): T {
val installReference = Installer.getInstallReference(APP_NAME)
val request = SessionNavigationRequest(
mockMvc, responseClass, installReference
)
val bean = request.getNavigationBean(selections)
return request.requestWithBean(bean).bean()
}
}
55 changes: 55 additions & 0 deletions src/test/resources/archives/case_claim_with_multi_select/suite.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,43 @@
</stack>
</action>
</detail>
<detail id="m1_case_short_lazy_load" lazy_loading="true">
<title>
<text>
<locale id="m1.case_short.title"/>
</text>
</title>
<field>
<header>
<text>
<locale id="m1.case_short.case_name_1.header"/>
</text>
</header>
<template>
<text>
<xpath function="case_name"/>
</text>
</template>
<sort type="string" order="1" direction="ascending">
<text>
<xpath function="case_name"/>
</text>
</sort>
</field>
<field>
<header>
<text>
<locale id="m1.case_short.case_name_1.header"/>
</text>
</header>
<template>
<text>
<xpath function="case_name"/>
</text>
</template>
</field>
<group function="string(case_name)" grid-header-rows="2" />
</detail>
<detail id="m1_case_short_autolaunch">
<title>
<text>
Expand Down Expand Up @@ -259,6 +296,18 @@
<instance-datum id="selected_cases" autoselect="true" nodeset="instance('casedb')/casedb/case[@case_type='case'][@status='open']" value="./@case_id" detail-select="m1_case_short_autolaunch_autoselect" detail-confirm="m1_case_long"/>
</session>
</entry>
<entry>
<form>http://openrosa.org/formdesigner/5CCB1614-68B3-44C0-A166-D63AA7C1D4FB</form>
<command id="m1-f3">
<text>
<locale id="forms.m1f1"/>
</text>
</command>
<instance id="casedb" src="jr://instance/casedb"/>
<session>
<instance-datum id="selected_cases" nodeset="instance('casedb')/casedb/case[@case_type='case'][@status='open']" value="./@case_id" detail-select="m1_case_short_lazy_load" detail-confirm="m1_case_long"/>
</session>
</entry>
<entry>
<form>http://openrosa.org/formdesigner/5CCB1614-68B3-44C0-A166-D63AA7C1D4FB</form>
<post url="http://localhost:8000/a/shubham/phone/claim-case/" relevant="$case_id != ''">
Expand Down Expand Up @@ -316,6 +365,12 @@
</text>
<command id="m2-f0"/>
</menu>
<menu id="m1-lazy-loading">
<text>
<locale id="modules.m1"/>
</text>
<command id="m1-f3"/>
</menu>
<endpoint id="inline_case_search_list_without_selection">
<stack>
<push>
Expand Down