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

Fixed displaying required questions with audio attachments #6332

Merged
merged 7 commits into from
Aug 22, 2024
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

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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?")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 -> {
Expand All @@ -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));
Expand Down Expand Up @@ -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);
}
});
}
Expand Down
25 changes: 0 additions & 25 deletions test-forms/src/main/resources/forms/requiredJR275.xml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0"?>
<h:html
xmlns="http://www.w3.org/2002/xforms"
xmlns:h="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jr="http://openrosa.org/javarosa"
xmlns:orx="http://openrosa.org/xforms"
xmlns:odk="http://www.opendatakit.org/xforms">
<h:head>
<h:title>required_question_with_audio</h:title>
<model odk:xforms-version="1.0.0">
<itext>
<translation lang="default" default="true()">
<text id="/data/q1:label">
<value>Required question with audio</value>
<value form="audio">jr://audio/blah.mp3</value>
</text>
</translation>
</itext>
<instance>
<data id="required_question_with_audio">
<q1/>
<meta>
<instanceID/>
</meta>
</data>
</instance>
<bind nodeset="/data/q1" type="string" required="true()"/>
<bind nodeset="/data/meta/instanceID" type="string" readonly="true()" jr:preload="uid"/>
</model>
</h:head>
<h:body>
<input ref="/data/q1">
<label ref="jr:itext('/data/q1:label')"/>
</input>
</h:body>
</h:html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0"?>
<h:html
xmlns="http://www.w3.org/2002/xforms"
xmlns:h="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jr="http://openrosa.org/javarosa"
xmlns:orx="http://openrosa.org/xforms"
xmlns:odk="http://www.opendatakit.org/xforms">
<h:head>
<h:title>required_question_with_custom_error_message</h:title>
<model odk:xforms-version="1.0.0">
<instance>
<data id="required_question_with_custom_error_message">
<q1/>
<meta>
<instanceID/>
<orx:audit/>
</meta>
</data>
</instance>
<bind nodeset="/data/orx:meta/audit" type="binary" />
<bind nodeset="/data/q1" type="string" required="true()" jr:requiredMsg="Custom message"/>
<bind nodeset="/data/meta/instanceID" type="string" readonly="true()" jr:preload="uid"/>
</model>
</h:head>
<h:body>
<input ref="/data/q1">
<label>Required question</label>
</input>
</h:body>
</h:html>