diff --git a/collect_app/src/main/java/org/odk/collect/android/formhierarchy/QuestionAnswerProcessor.kt b/collect_app/src/main/java/org/odk/collect/android/formhierarchy/QuestionAnswerProcessor.kt index fbc705f9e2c..3604bda99a7 100644 --- a/collect_app/src/main/java/org/odk/collect/android/formhierarchy/QuestionAnswerProcessor.kt +++ b/collect_app/src/main/java/org/odk/collect/android/formhierarchy/QuestionAnswerProcessor.kt @@ -27,11 +27,8 @@ object QuestionAnswerProcessor { if (!fep.answerText.isNullOrBlank() && Appearances.isMasked(fep) && - fep.controlType == Constants.CONTROL_INPUT && ( - fep.dataType == Constants.DATATYPE_TEXT || - fep.dataType == Constants.DATATYPE_INTEGER || - fep.dataType == Constants.DATATYPE_DECIMAL - ) + fep.controlType == Constants.CONTROL_INPUT && + fep.dataType == Constants.DATATYPE_TEXT ) { return "••••••••••" } diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/Appearances.kt b/collect_app/src/main/java/org/odk/collect/android/utilities/Appearances.kt index 5ae33fb4666..78d4067709f 100644 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/Appearances.kt +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/Appearances.kt @@ -16,6 +16,7 @@ package org.odk.collect.android.utilities import android.content.res.Configuration +import org.javarosa.core.model.Constants import org.javarosa.form.api.FormEntryPrompt import org.odk.collect.android.dynamicpreload.ExternalDataUtil import org.odk.collect.androidshared.utils.ScreenUtils @@ -195,6 +196,6 @@ object Appearances { @JvmStatic fun isMasked(prompt: FormEntryPrompt): Boolean { val appearance = getSanitizedAppearanceHint(prompt) - return appearance.contains(MASKED) + return appearance.contains(MASKED) && prompt.dataType == Constants.DATATYPE_TEXT } } diff --git a/collect_app/src/test/java/org/odk/collect/android/formhierarchy/QuestionAnswerProcessorTest.kt b/collect_app/src/test/java/org/odk/collect/android/formhierarchy/QuestionAnswerProcessorTest.kt index b7774d5a114..d615b0f6023 100644 --- a/collect_app/src/test/java/org/odk/collect/android/formhierarchy/QuestionAnswerProcessorTest.kt +++ b/collect_app/src/test/java/org/odk/collect/android/formhierarchy/QuestionAnswerProcessorTest.kt @@ -27,73 +27,57 @@ class QuestionAnswerProcessorTest { } @Test - fun noAnswerShouldBeDisplayedIfItDoesNotExistAndMaskedAppearanceIsUsedForTextAndNumberDataTypes() { - listOf( - Constants.DATATYPE_TEXT, - Constants.DATATYPE_INTEGER, - Constants.DATATYPE_DECIMAL - ).forEach { - val question = mock() - val prompt = MockFormEntryPromptBuilder() - .withQuestion(question) - .withDataType(it) - .withControlType(Constants.CONTROL_INPUT) - .withAppearance(Appearances.MASKED) - .build() + fun noAnswerShouldBeDisplayedIfItDoesNotExistAndMaskedAppearanceIsUsedForTextDataTypes() { + val question = mock() + val prompt = MockFormEntryPromptBuilder() + .withQuestion(question) + .withDataType(Constants.DATATYPE_TEXT) + .withControlType(Constants.CONTROL_INPUT) + .withAppearance(Appearances.MASKED) + .build() - val answer = QuestionAnswerProcessor.getQuestionAnswer(prompt, mock(), mock()) + val answer = QuestionAnswerProcessor.getQuestionAnswer(prompt, mock(), mock()) - assertThat(answer, equalTo("")) - } + assertThat(answer, equalTo("")) } @Test - fun noAnswerShouldBeDisplayedIfItIsEmptyAndMaskedAppearanceIsUsedForTextAndNumberDataTypes() { - listOf( - Constants.DATATYPE_TEXT, - Constants.DATATYPE_INTEGER, - Constants.DATATYPE_DECIMAL - ).forEach { - val question = mock() - val prompt = MockFormEntryPromptBuilder() - .withQuestion(question) - .withAnswerDisplayText("") - .withAppearance(Appearances.MASKED) - .withControlType(Constants.CONTROL_INPUT) - .withDataType(it) - .build() + fun noAnswerShouldBeDisplayedIfItIsEmptyAndMaskedAppearanceIsUsedForTextDataTypes() { + val question = mock() + val prompt = MockFormEntryPromptBuilder() + .withQuestion(question) + .withAnswerDisplayText("") + .withAppearance(Appearances.MASKED) + .withControlType(Constants.CONTROL_INPUT) + .withDataType(Constants.DATATYPE_TEXT) + .build() - val answer = QuestionAnswerProcessor.getQuestionAnswer(prompt, mock(), mock()) + val answer = QuestionAnswerProcessor.getQuestionAnswer(prompt, mock(), mock()) - assertThat(answer, equalTo("")) - } + assertThat(answer, equalTo("")) } @Test - fun maskedAnswerShouldBeDisplayedIfItExistAndMaskedAppearanceIsUsedForTextAndNumberDataTypes() { - listOf( - Constants.DATATYPE_TEXT, - Constants.DATATYPE_INTEGER, - Constants.DATATYPE_DECIMAL - ).forEach { - val question = mock() - val prompt = MockFormEntryPromptBuilder() - .withQuestion(question) - .withAnswerDisplayText("blah") - .withAppearance(Appearances.MASKED) - .withControlType(Constants.CONTROL_INPUT) - .withDataType(it) - .build() + fun maskedAnswerShouldBeDisplayedIfItExistAndMaskedAppearanceIsUsedForTextDataTypes() { + val question = mock() + val prompt = MockFormEntryPromptBuilder() + .withQuestion(question) + .withAnswerDisplayText("blah") + .withAppearance(Appearances.MASKED) + .withControlType(Constants.CONTROL_INPUT) + .withDataType(Constants.DATATYPE_TEXT) + .build() - val answer = QuestionAnswerProcessor.getQuestionAnswer(prompt, mock(), mock()) + val answer = QuestionAnswerProcessor.getQuestionAnswer(prompt, mock(), mock()) - assertThat(answer, equalTo("••••••••••")) - } + assertThat(answer, equalTo("••••••••••")) } @Test - fun originalAnswerShouldBeDisplayedIfItExistAndMaskedAppearanceIsUsedForDataTypesOtherThanTextAndNumber() { + fun originalAnswerShouldBeDisplayedIfItExistAndMaskedAppearanceIsUsedForDataTypesOtherThanText() { listOf( + Constants.DATATYPE_INTEGER, + Constants.DATATYPE_DECIMAL, Constants.DATATYPE_DATE_TIME, Constants.DATATYPE_DATE, Constants.DATATYPE_TIME, @@ -120,7 +104,7 @@ class QuestionAnswerProcessorTest { } @Test - fun originalAnswerShouldBeDisplayedIfItExistAndMaskedAppearanceIsUsedButControlTypeIsOtherThanInput() { + fun originalAnswerShouldBeDisplayedIfItExistAndMaskedAppearanceIsUsedForDataTypesAndControlTypeOtherThanInput() { listOf( Constants.CONTROL_RANGE, Constants.CONTROL_RANK, diff --git a/collect_app/src/test/java/org/odk/collect/android/utilities/AppearancesTest.kt b/collect_app/src/test/java/org/odk/collect/android/utilities/AppearancesTest.kt index e389e0090fb..aa718aa2363 100644 --- a/collect_app/src/test/java/org/odk/collect/android/utilities/AppearancesTest.kt +++ b/collect_app/src/test/java/org/odk/collect/android/utilities/AppearancesTest.kt @@ -19,6 +19,7 @@ import android.content.res.Configuration import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertFalse import junit.framework.TestCase.assertTrue +import org.javarosa.core.model.Constants import org.javarosa.form.api.FormEntryPrompt import org.junit.Test import org.mockito.kotlin.mock @@ -233,7 +234,8 @@ class AppearancesTest { } @Test - fun `useThousandSeparator returns false when 'thousands-sep' appearance is found but mixed with 'masked'`() { + fun `useThousandSeparator returns false when 'thousands-sep' appearance is found but mixed with 'masked' for text questions`() { + whenever(formEntryPrompt.dataType).thenReturn(Constants.DATATYPE_TEXT) whenever(formEntryPrompt.appearanceHint).thenReturn("thousands-sep masked") assertFalse(Appearances.useThousandSeparator(formEntryPrompt)) } @@ -369,6 +371,7 @@ class AppearancesTest { @Test fun `isMasked returns false when there is no appearance`() { + whenever(formEntryPrompt.dataType).thenReturn(Constants.DATATYPE_TEXT) assertFalse(Appearances.isMasked(formEntryPrompt)) whenever(formEntryPrompt.appearanceHint).thenReturn("") @@ -377,13 +380,25 @@ class AppearancesTest { @Test fun `isMasked returns false when non of supported appearances is found`() { + whenever(formEntryPrompt.dataType).thenReturn(Constants.DATATYPE_TEXT) whenever(formEntryPrompt.appearanceHint).thenReturn("blah") assertFalse(Appearances.isMasked(formEntryPrompt)) } @Test - fun `isMasked returns true when 'masked' appearance is found`() { + fun `isMasked returns true when 'masked' appearance is found for text questions`() { + whenever(formEntryPrompt.dataType).thenReturn(Constants.DATATYPE_TEXT) whenever(formEntryPrompt.appearanceHint).thenReturn("masked") assertTrue(Appearances.isMasked(formEntryPrompt)) } + + @Test + fun `isMasked returns false when 'masked' appearance is found for numeric questions`() { + whenever(formEntryPrompt.dataType).thenReturn(Constants.DATATYPE_INTEGER) + whenever(formEntryPrompt.appearanceHint).thenReturn("masked") + assertFalse(Appearances.isMasked(formEntryPrompt)) + + whenever(formEntryPrompt.dataType).thenReturn(Constants.DATATYPE_DECIMAL) + assertFalse(Appearances.isMasked(formEntryPrompt)) + } } diff --git a/collect_app/src/test/java/org/odk/collect/android/widgets/DecimalWidgetTest.java b/collect_app/src/test/java/org/odk/collect/android/widgets/DecimalWidgetTest.java index cd1293f7596..baeed76c95a 100644 --- a/collect_app/src/test/java/org/odk/collect/android/widgets/DecimalWidgetTest.java +++ b/collect_app/src/test/java/org/odk/collect/android/widgets/DecimalWidgetTest.java @@ -2,12 +2,14 @@ import androidx.annotation.NonNull; +import org.javarosa.core.model.Constants; import org.javarosa.core.model.QuestionDef; import org.javarosa.core.model.data.DecimalData; import org.javarosa.core.model.data.IAnswerData; import org.junit.Test; import org.mockito.Mock; import org.odk.collect.android.formentry.questions.QuestionDetails; +import org.odk.collect.android.utilities.Appearances; import org.odk.collect.android.widgets.base.GeneralStringWidgetTest; import java.text.NumberFormat; @@ -15,12 +17,13 @@ import java.util.Random; import static junit.framework.TestCase.assertEquals; +import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.when; -import static org.odk.collect.android.utilities.Appearances.MASKED; import static org.odk.collect.android.utilities.Appearances.THOUSANDS_SEP; import android.text.InputType; @@ -40,6 +43,7 @@ public class DecimalWidgetTest extends GeneralStringWidgetTest