diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/RequiredQuestionTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/RequiredQuestionTest.java deleted file mode 100644 index ebcbb49d7cd..00000000000 --- a/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/RequiredQuestionTest.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.odk.collect.android.feature.formentry; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; - -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import org.apache.commons.csv.CSVRecord; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.RuleChain; -import org.junit.runner.RunWith; -import org.odk.collect.android.support.StorageUtils; -import org.odk.collect.android.support.rules.CollectTestRule; -import org.odk.collect.android.support.rules.TestRuleChain; - -import java.io.IOException; -import java.util.List; - -// Issue number NODK-249 -@RunWith(AndroidJUnit4.class) -public class RequiredQuestionTest { - - public CollectTestRule rule = new CollectTestRule(); - - @Rule - public RuleChain copyFormChain = TestRuleChain.chain() - .around(rule); - - @Test - public void requiredQuestions_ShouldDisplayAsterisk_andCustomMessageIfSkipped() { - rule.startAtMainMenu() - .copyForm("requiredJR275.xml") - .startBlankForm("required") - .assertText("* Foo") //TestCase1 - .swipeToNextQuestionWithConstraintViolation("Custom required message"); //TestCase2 - } - - @Test - public void pressingValidateInOptionsMenuOnSameScreen_shouldUseLatestAnswers() { - rule.startAtMainMenu() - .copyForm("requiredJR275.xml") - .startBlankForm("required") - .answerQuestion("Foo", true, "blah") - .clickOptionsIcon() - .clickOnString(org.odk.collect.strings.R.string.validate) - .assertText(org.odk.collect.strings.R.string.success_form_validation) - .assertTextDoesNotExist("Custom required message"); - } - - @Test - public void pressingValidateInOptionsMenuOnDifferentScreen_shouldReturnToQuestionAndShowMessage() { - rule.startAtMainMenu() - .copyForm("requiredJR275.xml") - .startBlankForm("required") - .clickGoToArrow() - .clickGoToEnd() - .clickOptionsIcon() - .clickOnString(org.odk.collect.strings.R.string.validate) - .assertConstraintDisplayed("Custom required message") - .assertQuestion("Foo", true); - } - - @Test - public void pressingValidateInOptionsMenuOnDifferentScreen_shouldReturnToQuestionAndShowMessage_whenTheQuestionIsInFieldList() { - rule.startAtMainMenu() - .copyForm("requiredQuestionInFieldList.xml") - .startBlankForm("requiredQuestionInFieldList") - .clickGoToArrow() - .clickGoToEnd() - .clickOptionsIcon() - .clickOnString(org.odk.collect.strings.R.string.validate) - .assertConstraintDisplayed("Custom required message") - // Make sure both questions are still displayed on the same screen - .assertQuestion("Foo", true) - .assertQuestion("Bar", true); - } - - @Test - public void ifRequiredQuestionIsEmpty_shouldNotBeSavedToAuditLogWhenMovingForward() throws IOException { - rule.startAtMainMenu() - .copyForm("requiredJR275.xml") - .startBlankForm("required") - .swipeToNextQuestionWithConstraintViolation("Custom required message"); - - List auditLog = StorageUtils.getAuditLogForFirstInstance(); - assertThat(auditLog.size(), equalTo(1)); - assertThat(auditLog.get(0).get(0), equalTo("form start")); - } - - @Test - public void ifRequiredQuestionIsEmpty_shouldNotBeSavedToAuditLogWhenFormValidated() throws IOException { - rule.startAtMainMenu() - .copyForm("requiredJR275.xml") - .startBlankForm("required") - .clickOptionsIcon() - .clickOnString(org.odk.collect.strings.R.string.validate); - - List auditLog = StorageUtils.getAuditLogForFirstInstance(); - assertThat(auditLog.size(), equalTo(1)); - assertThat(auditLog.get(0).get(0), equalTo("form start")); - } - - @Test - public void ifRequiredQuestionIsInFieldListAndNotFirst_shouldBeValidatedProperly() { - rule.startAtMainMenu() - .copyForm("requiredQuestionInFieldList.xml") - .startBlankForm("requiredQuestionInFieldList") - .answerQuestion("Foo", true, "blah") - .swipeToNextQuestionWithConstraintViolation("Custom required message2") - .clickOptionsIcon() - .clickOnString(org.odk.collect.strings.R.string.validate) - .assertText("Custom required message2") - .clickGoToArrow() - .clickGoToEnd() - .clickSaveAndExitWithError("Custom required message2"); - } - - @Test // https://github.com/getodk/collect/issues/5847 - public void savingFormWithInvalidQuestion_shouldNotChangeTheCurrentQuestionIndex() { - rule.startAtMainMenu() - .copyForm("two-question-required.xml") - .startBlankForm("Two Question Required") - .clickSave() - .swipeToNextQuestion("What is your age?"); - } -} diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/RequiredQuestionTest.kt b/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/RequiredQuestionTest.kt new file mode 100644 index 00000000000..f6de4d0eb05 --- /dev/null +++ b/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/RequiredQuestionTest.kt @@ -0,0 +1,134 @@ +package org.odk.collect.android.feature.formentry + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.equalTo +import org.junit.Rule +import org.junit.Test +import org.junit.rules.RuleChain +import org.junit.runner.RunWith +import org.odk.collect.android.support.StorageUtils.getAuditLogForFirstInstance +import org.odk.collect.android.support.rules.CollectTestRule +import org.odk.collect.android.support.rules.TestRuleChain.chain +import org.odk.collect.strings.R + +@RunWith(AndroidJUnit4::class) +class RequiredQuestionTest { + var rule: CollectTestRule = CollectTestRule() + + @get:Rule + var ruleChain: RuleChain = chain() + .around(rule) + + @Test + fun requiredQuestionIsMarkedWithAnAsterisk() { + rule.startAtMainMenu() + .copyForm("required_question_with_custom_error_message.xml") + .startBlankForm("required_question_with_custom_error_message") + .assertQuestion("Required question", true) + } + + @Test // https://github.com/getodk/collect/issues/6327 + fun requiredQuestionWithAudioIsMarkedWithAnAsterisk() { + rule.startAtMainMenu() + .copyForm("required_question_with_audio.xml") + .startBlankForm("required_question_with_audio") + .swipeToNextQuestion("Required question with audio", true) + } + + @Test + fun requiredQuestionDisplaysACustomErrorMessageIfSpecified() { + rule.startAtMainMenu() + .copyForm("required_question_with_custom_error_message.xml") + .startBlankForm("required_question_with_custom_error_message") + .swipeToNextQuestionWithConstraintViolation("Custom message") + } + + @Test + fun validatingFormByPressingValidateInOptionsMenuOnSameScreen_usesNewlyAddedAnswers() { + rule.startAtMainMenu() + .copyForm("required_question_with_custom_error_message.xml") + .startBlankForm("required_question_with_custom_error_message") + .answerQuestion("* Required question", "blah") + .clickOptionsIcon() + .clickOnString(R.string.validate) + .assertText(R.string.success_form_validation) + .assertTextDoesNotExist("Custom message") + } + + @Test + fun validatingFormByPressingValidateInOptionsMenuOnDifferentScreen_movesToTheQuestionWithErrorAndDisplaysError() { + rule.startAtMainMenu() + .copyForm("required_question_with_custom_error_message.xml") + .startBlankForm("required_question_with_custom_error_message") + .clickGoToArrow() + .clickGoToEnd() + .clickOptionsIcon() + .clickOnString(R.string.validate) + .assertConstraintDisplayed("Custom message") + .assertQuestion("Required question", true) + } + + @Test + fun validatingFormByPressingValidateInOptionsMenuOnDifferentScreen_movesToTheQuestionWithErrorAndDisplaysError_whenTheQuestionIsInFieldList() { + rule.startAtMainMenu() + .copyForm("requiredQuestionInFieldList.xml") + .startBlankForm("requiredQuestionInFieldList") + .clickGoToArrow() + .clickGoToEnd() + .clickOptionsIcon() + .clickOnString(R.string.validate) + .assertConstraintDisplayed("Custom required message") // Make sure both questions are still displayed on the same screen + .assertQuestion("Foo", true) + .assertQuestion("Bar", true) + } + + @Test + fun emptyRequiredQuestion_isNotSavedToAuditLogOnMovingForward() { + rule.startAtMainMenu() + .copyForm("required_question_with_custom_error_message.xml") + .startBlankForm("required_question_with_custom_error_message") + .swipeToNextQuestionWithConstraintViolation("Custom message") + + val auditLog = getAuditLogForFirstInstance() + assertThat(auditLog.size, equalTo(1)) + assertThat(auditLog[0][0], equalTo("form start")) + } + + @Test + fun emptyRequiredQuestion_isNotSavedToAuditLogOnFormValidation() { + rule.startAtMainMenu() + .copyForm("required_question_with_custom_error_message.xml") + .startBlankForm("required_question_with_custom_error_message") + .clickOptionsIcon() + .clickOnString(R.string.validate) + + val auditLog = getAuditLogForFirstInstance() + assertThat(auditLog.size, equalTo(1)) + assertThat(auditLog[0][0], equalTo("form start")) + } + + @Test + fun emptyRequiredQuestionInFieldListAndNotFirst_isValidatedProperly() { + rule.startAtMainMenu() + .copyForm("requiredQuestionInFieldList.xml") + .startBlankForm("requiredQuestionInFieldList") + .answerQuestion("Foo", true, "blah") + .swipeToNextQuestionWithConstraintViolation("Custom required message2") + .clickOptionsIcon() + .clickOnString(R.string.validate) + .assertText("Custom required message2") + .clickGoToArrow() + .clickGoToEnd() + .clickSaveAndExitWithError("Custom required message2") + } + + @Test // https://github.com/getodk/collect/issues/5847 + fun savingFormWithInvalidQuestion_doesNotChangeTheCurrentQuestionIndex() { + rule.startAtMainMenu() + .copyForm("two-question-required.xml") + .startBlankForm("Two Question Required") + .clickSave() + .swipeToNextQuestion("What is your age?") + } +} diff --git a/collect_app/src/main/java/org/odk/collect/android/formentry/questions/AudioVideoImageTextLabel.java b/collect_app/src/main/java/org/odk/collect/android/formentry/questions/AudioVideoImageTextLabel.java index 34ebd91fb43..e50dcba2c8f 100644 --- a/collect_app/src/main/java/org/odk/collect/android/formentry/questions/AudioVideoImageTextLabel.java +++ b/collect_app/src/main/java/org/odk/collect/android/formentry/questions/AudioVideoImageTextLabel.java @@ -53,7 +53,6 @@ public class AudioVideoImageTextLabel extends RelativeLayout implements View.OnC private TextView textLabel; private int originalTextColor; private int playTextColor = Color.BLUE; - private CharSequence questionText; private SelectItemClickListener listener; private File videoFile; private File bigImageFile; @@ -72,8 +71,6 @@ public AudioVideoImageTextLabel(Context context, AttributeSet attrs) { } public void setTextView(TextView questionText) { - this.questionText = questionText.getText(); - textLabel = questionText; textLabel.setId(R.id.text_label); textLabel.setOnClickListener(v -> { @@ -87,8 +84,6 @@ public void setTextView(TextView questionText) { } public void setText(String questionText, boolean isRequiredQuestion, float fontSize) { - this.questionText = questionText; - if (questionText != null && !questionText.isEmpty()) { textLabel.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSize); textLabel.setText(FormEntryPromptUtils.styledQuestionText(questionText, isRequiredQuestion)); @@ -216,8 +211,6 @@ private void setupAudioButton(String audioURI, AudioHelper audioHelper) { textLabel.setTextColor(playTextColor); } else { textLabel.setTextColor(originalTextColor); - // then set the text to our original (brings back any html formatting) - textLabel.setText(questionText); } }); } diff --git a/test-forms/src/main/resources/forms/requiredJR275.xml b/test-forms/src/main/resources/forms/requiredJR275.xml deleted file mode 100644 index 49acd8c24e4..00000000000 --- a/test-forms/src/main/resources/forms/requiredJR275.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - required - - - - - - - - - - - - - - - - - - - - - diff --git a/test-forms/src/main/resources/forms/required_question_with_audio.xml b/test-forms/src/main/resources/forms/required_question_with_audio.xml new file mode 100644 index 00000000000..2fc3d88ef9f --- /dev/null +++ b/test-forms/src/main/resources/forms/required_question_with_audio.xml @@ -0,0 +1,38 @@ + + + + required_question_with_audio + + + + + Required question with audio + jr://audio/blah.mp3 + + + + + + + + + + + + + + + + + + + diff --git a/test-forms/src/main/resources/forms/required_question_with_custom_error_message.xml b/test-forms/src/main/resources/forms/required_question_with_custom_error_message.xml new file mode 100644 index 00000000000..152625f7ff8 --- /dev/null +++ b/test-forms/src/main/resources/forms/required_question_with_custom_error_message.xml @@ -0,0 +1,32 @@ + + + + required_question_with_custom_error_message + + + + + + + + + + + + + + + + + + + + +