Skip to content

Commit

Permalink
Use XPathProcessor to detect pulldata
Browse files Browse the repository at this point in the history
  • Loading branch information
seadowg committed Dec 4, 2023
1 parent b396dcd commit 101f858
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package org.odk.collect.android.dynamicpreload

import org.javarosa.core.model.FormDef
import org.javarosa.core.model.QuestionDef
import org.javarosa.core.util.externalizable.ExtUtil
import org.javarosa.core.util.externalizable.Externalizable
import org.javarosa.core.util.externalizable.PrototypeFactory
import org.javarosa.xform.parse.IXFormParserFactory
import org.javarosa.xform.parse.XFormParser
import org.javarosa.xpath.expr.XPathExpression
import java.io.DataInputStream
import java.io.DataOutputStream

Expand All @@ -19,10 +21,28 @@ class DynamicPreloadXFormParserFactory(base: IXFormParserFactory) :
}
}

class DynamicPreloadParseProcessor : XFormParser.FormDefProcessor {
class DynamicPreloadParseProcessor :
XFormParser.XPathProcessor,
XFormParser.QuestionProcessor,
XFormParser.FormDefProcessor {

private var containsPullData = false
private var containsSearch = false

override fun processXPath(xPathExpression: XPathExpression) {
if (xPathExpression.containsFunc("pulldata")) {
containsPullData = true
}
}

override fun processQuestion(question: QuestionDef) {
if (ExternalDataUtil.getSearchXPathExpression(question.appearanceAttr) != null) {
containsSearch = true
}
}

override fun processFormDef(formDef: FormDef) {
formDef.extras.put(DynamicPreloadExtra(true))
formDef.extras.put(DynamicPreloadExtra(containsPullData || containsSearch))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,75 @@ package org.odk.collect.android.dynamicpreload
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
import org.javarosa.core.model.FormDef
import org.javarosa.core.model.QuestionDef
import org.javarosa.xpath.expr.XPathExpression
import org.junit.Test
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock

class DynamicPreloadParseProcessorTest {

private val processor = DynamicPreloadParseProcessor()

/**
* This is currently a "stub" implementation until we have a good way of determining whether
* a form contains search/pulldata.
*/
@Test
fun `usesDynamicPreload is true`() {
fun `usesDynamicPreload is false when xpath does not contain pulldata`() {
val formDef = FormDef()

processor.processXPath(createNonPullDataExpression())
processor.processFormDef(formDef)
assertThat(
formDef.extras.get(DynamicPreloadExtra::class.java).usesDynamicPreload,
equalTo(false)
)
}

@Test
fun `usesDynamicPreload is true when xpath does contain pulldata`() {
val formDef = FormDef()

processor.processXPath(createPullDataExpression())
processor.processFormDef(formDef)
assertThat(
formDef.extras.get(DynamicPreloadExtra::class.java).usesDynamicPreload,
equalTo(true)
)
}

@Test
fun `usesDynamicPreload is false when question appearance does not contain search`() {
val formDef = FormDef()

processor.processQuestion(createQuestion(appearance = "minimal"))
processor.processFormDef(formDef)
assertThat(
formDef.extras.get(DynamicPreloadExtra::class.java).usesDynamicPreload,
equalTo(false)
)
}

@Test
fun `usesDynamicPreload is true when question appearance does contain search`() {
val formDef = FormDef()

processor.processQuestion(createQuestion(appearance = "search('fruits')"))
processor.processFormDef(formDef)
assertThat(
formDef.extras.get(DynamicPreloadExtra::class.java).usesDynamicPreload,
equalTo(true)
)
}

private fun createNonPullDataExpression() = mock<XPathExpression> {
on { containsFunc("pulldata") } doReturn false
}

private fun createPullDataExpression() = mock<XPathExpression> {
on { containsFunc("pulldata") } doReturn true
}

private fun createQuestion(appearance: String): QuestionDef {
return mock() {
on { appearanceAttr } doReturn appearance
}
}
}

0 comments on commit 101f858

Please sign in to comment.