From 264800115977d3196b0b20a423023b8a1f48e18e Mon Sep 17 00:00:00 2001 From: "Mr. 17" Date: Sat, 27 Jan 2024 03:07:23 +0530 Subject: [PATCH] Fix part of #5070: Display empty answer message in number input interaction (#5310) ## Explanation Fixes part of #5070 Enables the `submit_answer_button` when the pending answer is empty. Instead of disabling the button, an error message, stating "_**Enter a number to continue.**_", is now displayed when the user attempts to submit a blank answer. https://github.com/oppia/oppia-android/assets/84731134/820021bb-94bb-432f-b545-e3bc89e49e17 ## Essential Checklist - [x] The PR title and explanation each start with "Fix #bugnum: " (If this PR fixes part of an issue, prefix the title with "Fix part of #bugnum: ...".) - [x] Any changes to [scripts/assets](https://github.com/oppia/oppia-android/tree/develop/scripts/assets) files have their rationale included in the PR explanation. - [x] The PR follows the [style guide](https://github.com/oppia/oppia-android/wiki/Coding-style-guide). - [x] The PR does not contain any unnecessary code changes from Android Studio ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#undo-unnecessary-changes)). - [x] The PR is made from a branch that's **not** called "develop" and is up-to-date with "develop". - [x] The PR is **assigned** to the appropriate reviewers ([reference](https://github.com/oppia/oppia-android/wiki/Guidance-on-submitting-a-PR#clarification-regarding-assignees-and-reviewers-section)). ## For UI-specific PRs only If your PR includes UI-related changes, then: - Add screenshots for portrait/landscape for both a tablet & phone of the before & after UI changes - For the screenshots above, include both English and pseudo-localized (RTL) screenshots (see [RTL guide](https://github.com/oppia/oppia-android/wiki/RTL-Guidelines)) - Add a video showing the full UX flow with a screen reader enabled (see [accessibility guide](https://github.com/oppia/oppia-android/wiki/Accessibility-A11y-Guide)) - For PRs introducing new UI elements or color changes, both light and dark mode screenshots must be included - Add a screenshot demonstrating that you ran affected Espresso tests locally & that they're passing --------- Co-authored-by: Adhiambo Peres <59600948+adhiamboperes@users.noreply.github.com> --- .../app/parser/StringToNumberParser.kt | 6 ++++- .../itemviewmodel/NumericInputViewModel.kt | 27 ++++++++++++------- app/src/main/res/values/strings.xml | 1 + .../InputInteractionViewTestActivityTest.kt | 18 +++++++++++++ 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/parser/StringToNumberParser.kt b/app/src/main/java/org/oppia/android/app/parser/StringToNumberParser.kt index 5b625623ad2..ae0c3771b46 100644 --- a/app/src/main/java/org/oppia/android/app/parser/StringToNumberParser.kt +++ b/app/src/main/java/org/oppia/android/app/parser/StringToNumberParser.kt @@ -41,6 +41,9 @@ class StringToNumberParser { * detection should be done using [getRealTimeAnswerError], instead. */ fun getSubmitTimeError(text: String): NumericInputParsingError { + if (text.isBlank()) { + return NumericInputParsingError.EMPTY_INPUT + } if (text.length > 15) { return NumericInputParsingError.NUMBER_TOO_LONG } @@ -57,7 +60,8 @@ class StringToNumberParser { VALID(error = null), INVALID_FORMAT(error = R.string.number_error_invalid_format), STARTING_WITH_FLOATING_POINT(error = R.string.number_error_starting_with_floating_point), - NUMBER_TOO_LONG(error = R.string.number_error_larger_than_fifteen_characters); + NUMBER_TOO_LONG(error = R.string.number_error_larger_than_fifteen_characters), + EMPTY_INPUT(error = R.string.number_error_empty_input); /** * Returns the string corresponding to this error's string resources, or null if there is none. diff --git a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/NumericInputViewModel.kt b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/NumericInputViewModel.kt index 93bdddde6f0..04174714b4f 100644 --- a/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/NumericInputViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/player/state/itemviewmodel/NumericInputViewModel.kt @@ -36,25 +36,34 @@ class NumericInputViewModel private constructor( override fun onPropertyChanged(sender: Observable, propertyId: Int) { interactionAnswerErrorOrAvailabilityCheckReceiver.onPendingAnswerErrorOrAvailabilityCheck( pendingAnswerError, - answerText.isNotEmpty() + inputAnswerAvailable = true // Allow blank answer submission. ) } } errorMessage.addOnPropertyChangedCallback(callback) isAnswerAvailable.addOnPropertyChangedCallback(callback) + + // Initializing with default values so that submit button is enabled by default. + interactionAnswerErrorOrAvailabilityCheckReceiver.onPendingAnswerErrorOrAvailabilityCheck( + pendingAnswerError = null, + inputAnswerAvailable = true + ) } - /** It checks the pending error for the current numeric input, and correspondingly updates the error string based on the specified error category. */ + /** + * It checks the pending error for the current numeric input, and correspondingly updates the + * error string based on the specified error category. + */ override fun checkPendingAnswerError(category: AnswerErrorCategory): String? { - if (answerText.isNotEmpty()) { - pendingAnswerError = when (category) { - AnswerErrorCategory.REAL_TIME -> + pendingAnswerError = when (category) { + AnswerErrorCategory.REAL_TIME -> + if (answerText.isNotEmpty()) stringToNumberParser.getRealTimeAnswerError(answerText.toString()) .getErrorMessageFromStringRes(resourceHandler) - AnswerErrorCategory.SUBMIT_TIME -> - stringToNumberParser.getSubmitTimeError(answerText.toString()) - .getErrorMessageFromStringRes(resourceHandler) - } + else null + AnswerErrorCategory.SUBMIT_TIME -> + stringToNumberParser.getSubmitTimeError(answerText.toString()) + .getErrorMessageFromStringRes(resourceHandler) } errorMessage.set(pendingAnswerError) return pendingAnswerError diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cc2b39169e5..419a4fde901 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -170,6 +170,7 @@ Please begin your answer with a number (e.g.,”0” in 0.5). Please enter a valid number. The answer can contain at most 15 digits (0–9) or symbols (. or -). + Enter a number to continue. Please write a ratio that consists of digits separated by colons (e.g. 1:2 or 1:2:3). Please enter a valid ratio (e.g. 1:2 or 1:2:3). Your answer has two colons (:) next to each other. diff --git a/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt index 0bd03beb6ae..01f4f9872bb 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/testing/InputInteractionViewTestActivityTest.kt @@ -250,6 +250,24 @@ class InputInteractionViewTestActivityTest { } } + @Test + @DisableAccessibilityChecks // Disabled, as InputInteractionViewTestActivity is a test file and + // will not be used by user + fun testNumericInput_withBlankInput_submit_emptyInputErrorIsDisplayed() { + ActivityScenario.launch(InputInteractionViewTestActivity::class.java).use { + scrollToSubmitButton() + onView(withId(R.id.submit_button)).check(matches(isDisplayed())).perform(click()) + onView(withId(R.id.number_input_error)) + .check( + matches( + withText( + R.string.number_error_empty_input + ) + ) + ) + } + } + @Test @DisableAccessibilityChecks // Disabled, as InputInteractionViewTestActivity is a test file and // will not be used by user