diff --git a/collect_app/src/main/java/org/odk/collect/android/dynamicpreload/DynamicPreloadXFormParserFactory.kt b/collect_app/src/main/java/org/odk/collect/android/dynamicpreload/DynamicPreloadXFormParserFactory.kt index d9a8cdc369a..24566823e4a 100644 --- a/collect_app/src/main/java/org/odk/collect/android/dynamicpreload/DynamicPreloadXFormParserFactory.kt +++ b/collect_app/src/main/java/org/odk/collect/android/dynamicpreload/DynamicPreloadXFormParserFactory.kt @@ -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 @@ -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)) } } diff --git a/collect_app/src/test/java/org/odk/collect/android/dynamicpreload/DynamicPreloadParseProcessorTest.kt b/collect_app/src/test/java/org/odk/collect/android/dynamicpreload/DynamicPreloadParseProcessorTest.kt index e0296f96cc7..0d4d7130648 100644 --- a/collect_app/src/test/java/org/odk/collect/android/dynamicpreload/DynamicPreloadParseProcessorTest.kt +++ b/collect_app/src/test/java/org/odk/collect/android/dynamicpreload/DynamicPreloadParseProcessorTest.kt @@ -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 { + on { containsFunc("pulldata") } doReturn false + } + + private fun createPullDataExpression() = mock { + on { containsFunc("pulldata") } doReturn true + } + + private fun createQuestion(appearance: String): QuestionDef { + return mock() { + on { appearanceAttr } doReturn appearance + } + } }