From ad520870cac158465be18fb390f1436aeabfe8b5 Mon Sep 17 00:00:00 2001 From: Vraj Desai <43074241+vrajdesai78@users.noreply.github.com> Date: Tue, 13 Sep 2022 00:11:48 +0530 Subject: [PATCH] Fixes #3892: Locked chapter item selection change is incorrect (#4573) * Fixed UX for users with visual imparity * klint issue fixed --- .../app/story/StoryFragmentPresenter.kt | 44 +++++++++------- .../android/app/story/StoryFragmentTest.kt | 50 +++++++++++++++++++ 2 files changed, 75 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt index ff4037415af..24795c0024c 100644 --- a/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/story/StoryFragmentPresenter.kt @@ -35,6 +35,7 @@ import org.oppia.android.databinding.StoryFragmentBinding import org.oppia.android.databinding.StoryHeaderViewBinding import org.oppia.android.domain.exploration.ExplorationDataController import org.oppia.android.domain.oppialogger.OppiaLogger +import org.oppia.android.util.accessibility.AccessibilityService import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData import org.oppia.android.util.gcsresource.DefaultResourceBucketName @@ -63,6 +64,9 @@ class StoryFragmentPresenter @Inject constructor( @Inject lateinit var storyViewModel: StoryViewModel + @Inject + lateinit var accessibilityService: AccessibilityService + fun handleCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -181,28 +185,30 @@ class StoryFragmentPresenter @Inject constructor( storyItemViewModel.missingPrerequisiteChapterTitle ) val chapterLockedSpannable = SpannableString(missingPrerequisiteSummary) - val clickableSpan = object : ClickableSpan() { - override fun onClick(widget: View) { - smoothScrollToPosition(storyItemViewModel.index - 1) - } + if (!accessibilityService.isScreenReaderEnabled()) { + val clickableSpan = object : ClickableSpan() { + override fun onClick(widget: View) { + smoothScrollToPosition(storyItemViewModel.index - 1) + } - override fun updateDrawState(ds: TextPaint) { - super.updateDrawState(ds) - ds.isUnderlineText = false + override fun updateDrawState(ds: TextPaint) { + super.updateDrawState(ds) + ds.isUnderlineText = false + } } + chapterLockedSpannable.setSpan( + clickableSpan, + /* start= */ LOCKED_CARD_PREFIX_LENGTH, + /* end= */ chapterLockedSpannable.length - LOCKED_CARD_SUFFIX_LENGTH, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + chapterLockedSpannable.setSpan( + TypefaceSpan("sans-serif-medium"), + /* start= */ LOCKED_CARD_PREFIX_LENGTH, + /* end= */ chapterLockedSpannable.length - LOCKED_CARD_SUFFIX_LENGTH, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) } - chapterLockedSpannable.setSpan( - clickableSpan, - /* start= */ LOCKED_CARD_PREFIX_LENGTH, - /* end= */ chapterLockedSpannable.length - LOCKED_CARD_SUFFIX_LENGTH, - Spanned.SPAN_EXCLUSIVE_EXCLUSIVE - ) - chapterLockedSpannable.setSpan( - TypefaceSpan("sans-serif-medium"), - /* start= */ LOCKED_CARD_PREFIX_LENGTH, - /* end= */ chapterLockedSpannable.length - LOCKED_CARD_SUFFIX_LENGTH, - Spanned.SPAN_EXCLUSIVE_EXCLUSIVE - ) binding.htmlContent = chapterLockedSpannable binding.chapterSummary.movementMethod = LinkMovementMethod.getInstance() } diff --git a/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt index 1df903d3ae5..25bf332b34f 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/story/StoryFragmentTest.kt @@ -126,6 +126,7 @@ import org.oppia.android.testing.threading.TestDispatcherModule import org.oppia.android.testing.time.FakeOppiaClock import org.oppia.android.testing.time.FakeOppiaClockModule import org.oppia.android.util.accessibility.AccessibilityTestModule +import org.oppia.android.util.accessibility.FakeAccessibilityService import org.oppia.android.util.caching.AssetModule import org.oppia.android.util.caching.testing.CachingTestModule import org.oppia.android.util.gcsresource.GcsResourceModule @@ -175,6 +176,9 @@ class StoryFragmentTest { @Inject lateinit var fakeOppiaClock: FakeOppiaClock + @Inject + lateinit var accessibilityService: FakeAccessibilityService + @Captor lateinit var listCaptor: ArgumentCaptor> @@ -557,6 +561,52 @@ class StoryFragmentTest { } } + @Test + fun testStoryFragment_checkClickableSpanWithoutScreenReader_isClickable() { + launch(createFractionsStoryActivityIntent()).use { + accessibilityService.setScreenReaderEnabled(false) + testCoroutineDispatchers.runCurrent() + onView(isRoot()).perform(orientationLandscape()) + onView(allOf(withId(R.id.story_chapter_list))).perform( + scrollToPosition( + 2 + ) + ) + onView( + atPositionOnView( + recyclerViewId = R.id.story_chapter_list, + position = 2, + targetViewId = R.id.chapter_summary + ) + ).check( + matches(hasClickableSpanWithText("Chapter 1: What is a Fraction?")) + ) + } + } + + @Test + fun testStoryFragment_checkClickableSpanWithScreenReader_isNotClickable() { + launch(createFractionsStoryActivityIntent()).use { + accessibilityService.setScreenReaderEnabled(true) + testCoroutineDispatchers.runCurrent() + onView(isRoot()).perform(orientationLandscape()) + onView(allOf(withId(R.id.story_chapter_list))).perform( + scrollToPosition( + 2 + ) + ) + onView( + atPositionOnView( + recyclerViewId = R.id.story_chapter_list, + position = 2, + targetViewId = R.id.chapter_summary + ) + ).check( + matches(not(hasClickableSpanWithText("Chapter 1: What is a Fraction?"))) + ) + } + } + @Test fun testStoryFragment_clickPrerequisiteChapter_prerequisiteChapterCardIsDisplayed() { launch(createFractionsStoryActivityIntent()).use {