diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/ExternalSelectsTest.kt b/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/ExternalSelectsTest.kt index 35ab9601b82..1cb7abf7c82 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/ExternalSelectsTest.kt +++ b/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/ExternalSelectsTest.kt @@ -56,4 +56,23 @@ class ExternalSelectsTest { .assertText("File: $formsDirPath/search_and_select-media/nombre.csv is missing.") .assertText("File: $formsDirPath/search_and_select-media/nombre2.csv is missing.") } + + @Test + fun dynamicChoicesCanBeMixedWithNumericInternalOnes() { + rule.startAtMainMenu() + .copyForm("dynamic_and_static_choices.xml", listOf("fruits.csv")) + .startBlankForm("dynamic_and_static_choices") + .assertTexts("Mango", "Oranges", "Strawberries", "None of the above") + } + + @Test + fun missingFileMessage_shouldBeDisplayedIfDynamicChoicesUsedButTheConfigurationRowIsMissing() { + val formsDirPath = StoragePathProvider().getOdkDirPath(StorageSubdirectory.FORMS) + + rule.startAtMainMenu() + .copyForm("dynamic_and_static_choices.xml", listOf("fruits.csv")) + .startBlankForm("dynamic_and_static_choices") + .swipeToNextQuestion("Choose a number") + .assertText("File: $formsDirPath/dynamic_and_static_choices-media/numbers.csv is missing.") + } } diff --git a/collect_app/src/main/java/org/odk/collect/android/dynamicpreload/ExternalDataUtil.java b/collect_app/src/main/java/org/odk/collect/android/dynamicpreload/ExternalDataUtil.java index fddf9501431..28c3419fd5a 100644 --- a/collect_app/src/main/java/org/odk/collect/android/dynamicpreload/ExternalDataUtil.java +++ b/collect_app/src/main/java/org/odk/collect/android/dynamicpreload/ExternalDataUtil.java @@ -167,6 +167,10 @@ public static ArrayList populateExternalChoices(FormEntryPrompt fo XPathFuncExpr xpathfuncexpr, FormController formController) throws FileNotFoundException { try { List selectChoices = formEntryPrompt.getSelectChoices(); + if (!containsConfigurationChoice(selectChoices)) { + String filePath = getFilePath(xpathfuncexpr, formController); + throw new FileNotFoundException(filePath); + } ArrayList returnedChoices = new ArrayList<>(); for (SelectChoice selectChoice : selectChoices) { String value = selectChoice.getValue(); @@ -212,14 +216,7 @@ public static ArrayList populateExternalChoices(FormEntryPrompt fo } return returnedChoices; } catch (Exception e) { - String fileName = String.valueOf(xpathfuncexpr.args[0].eval(null, null)); - if (!fileName.endsWith(".csv")) { - fileName = fileName + ".csv"; - } - String filePath = fileName; - if (formController != null) { - filePath = formController.getMediaFolder() + File.separator + fileName; - } + String filePath = getFilePath(xpathfuncexpr, formController); if (!new File(filePath).exists()) { throw new FileNotFoundException(filePath); } @@ -345,4 +342,30 @@ public static boolean isAnInteger(String value) { return false; } } + + /** + * The config row is a special row in the choices worksheet that defines how + * choices are mapped from an external .csv file with list_name, name and label, + * where these correspond to columns in the .csv file. + */ + private static boolean containsConfigurationChoice(List selectChoices) { + for (SelectChoice choice : selectChoices) { + if (!isAnInteger(choice.getValue())) { + return true; + } + } + return false; + } + + private static String getFilePath(XPathFuncExpr xpathfuncexpr, FormController formController) { + String fileName = String.valueOf(xpathfuncexpr.args[0].eval(null, null)); + if (!fileName.endsWith(".csv")) { + fileName = fileName + ".csv"; + } + String filePath = fileName; + if (formController != null) { + filePath = formController.getMediaFolder() + File.separator + fileName; + } + return filePath; + } } diff --git a/test-forms/src/main/resources/forms/dynamic_and_static_choices.xml b/test-forms/src/main/resources/forms/dynamic_and_static_choices.xml new file mode 100644 index 00000000000..2f51e75fd3b --- /dev/null +++ b/test-forms/src/main/resources/forms/dynamic_and_static_choices.xml @@ -0,0 +1,51 @@ + + + + dynamic_and_static_choices + + + + + + + + + + + + + + + + + + + + + name_key + + + + 0 + + + + + + + 0 + + + + 1 + + + + \ No newline at end of file