diff --git a/app/src/main/java/org/oppia/android/app/help/thirdparty/LicenseTextViewerActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/help/thirdparty/LicenseTextViewerActivityPresenter.kt index d4c5c34b262..64ecbf6e897 100644 --- a/app/src/main/java/org/oppia/android/app/help/thirdparty/LicenseTextViewerActivityPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/help/thirdparty/LicenseTextViewerActivityPresenter.kt @@ -6,6 +6,7 @@ import org.oppia.android.R import org.oppia.android.app.activity.ActivityScope import org.oppia.android.app.translation.AppLanguageResourceHandler import org.oppia.android.databinding.LicenseTextViewerActivityBinding +import org.oppia.android.util.accessibility.AccessibilityService import javax.inject.Inject /** The presenter for [LicenseTextViewerActivity]. */ @@ -14,6 +15,7 @@ class LicenseTextViewerActivityPresenter @Inject constructor( private val activity: AppCompatActivity, private val resourceHandler: AppLanguageResourceHandler ) { + @Inject lateinit var accessibilityService: AccessibilityService /** Handles onCreate() method of the [LicenseTextViewerActivity]. */ fun handleOnCreate(dependencyIndex: Int, licenseIndex: Int) { @@ -44,8 +46,10 @@ class LicenseTextViewerActivityPresenter @Inject constructor( (activity as LicenseTextViewerActivity).finish() } - binding.licenseTextViewerActivityToolbarTitle.setOnClickListener { - binding.licenseTextViewerActivityToolbarTitle.isSelected = true + if (!accessibilityService.isScreenReaderEnabled()) { + binding.licenseTextViewerActivityToolbarTitle.setOnClickListener { + binding.licenseTextViewerActivityToolbarTitle.isSelected = true + } } if (getLicenseTextViewerFragment() == null) { diff --git a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt index 5d1d0414196..3efadb513de 100644 --- a/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/player/exploration/ExplorationActivityPresenter.kt @@ -38,6 +38,7 @@ import org.oppia.android.domain.exploration.ExplorationDataController import org.oppia.android.domain.oppialogger.OppiaLogger import org.oppia.android.domain.survey.SurveyGatingController import org.oppia.android.domain.translation.TranslationController +import org.oppia.android.util.accessibility.AccessibilityService import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData import javax.inject.Inject @@ -61,6 +62,9 @@ class ExplorationActivityPresenter @Inject constructor( private val resourceHandler: AppLanguageResourceHandler, private val surveyGatingController: SurveyGatingController ) { + @Inject + lateinit var accessibilityService: AccessibilityService + private lateinit var explorationToolbar: Toolbar private lateinit var explorationToolbarTitle: TextView private lateinit var profileId: ProfileId @@ -89,7 +93,7 @@ class ExplorationActivityPresenter @Inject constructor( parentScreen: ExplorationActivityParams.ParentScreen, isCheckpointingEnabled: Boolean ) { - binding = DataBindingUtil.setContentView( + binding = DataBindingUtil.setContentView( activity, R.layout.exploration_activity ) @@ -102,8 +106,10 @@ class ExplorationActivityPresenter @Inject constructor( explorationToolbarTitle = binding.explorationToolbarTitle activity.setSupportActionBar(explorationToolbar) - binding.explorationToolbarTitle.setOnClickListener { - binding.explorationToolbarTitle.isSelected = true + if (!accessibilityService.isScreenReaderEnabled()) { + binding.explorationToolbarTitle.setOnClickListener { + binding.explorationToolbarTitle.isSelected = true + } } binding.explorationToolbar.setNavigationOnClickListener { @@ -181,7 +187,11 @@ class ExplorationActivityPresenter @Inject constructor( activity.supportFragmentManager.beginTransaction().add( R.id.exploration_fragment_placeholder, ExplorationFragment.newInstance( - profileId, topicId, storyId, explorationId, readingTextSize + profileId, + topicId, + storyId, + explorationId, + readingTextSize ), TAG_EXPLORATION_FRAGMENT ).commitNow() @@ -211,7 +221,8 @@ class ExplorationActivityPresenter @Inject constructor( } R.id.action_help -> { val intent = HelpActivity.createHelpActivityIntent( - activity, profileId.internalId, + activity, + profileId.internalId, /* isFromNavigationDrawer= */false ) fontScaleConfigurationUtil.adjustFontScale(activity, ReadingTextSize.MEDIUM_TEXT_SIZE) @@ -266,7 +277,8 @@ class ExplorationActivityPresenter @Inject constructor( // without deleting any checkpoints. if (::oldestCheckpointExplorationId.isInitialized) { explorationDataController.deleteExplorationProgressById( - profileId, oldestCheckpointExplorationId + profileId, + oldestCheckpointExplorationId ) } stopExploration(isCompletion = false) @@ -340,7 +352,8 @@ class ExplorationActivityPresenter @Inject constructor( explorationLiveData.observe(activity) { explorationToolbarTitle.text = translationController.extractString( - it.exploration.translatableTitle, it.writtenTranslationContext + it.exploration.translatableTitle, + it.writtenTranslationContext ) } } @@ -363,7 +376,9 @@ class ExplorationActivityPresenter @Inject constructor( return when (ephemeralExpResult) { is AsyncResult.Failure -> { oppiaLogger.e( - "ExplorationActivity", "Failed to retrieve answer outcome", ephemeralExpResult.error + "ExplorationActivity", + "Failed to retrieve answer outcome", + ephemeralExpResult.error ) EphemeralExploration.getDefaultInstance() } @@ -472,7 +487,9 @@ class ExplorationActivityPresenter @Inject constructor( } is AsyncResult.Failure -> { oppiaLogger.e( - "ExplorationActivity", "Failed to retrieve oldest saved checkpoint details.", it.error + "ExplorationActivity", + "Failed to retrieve oldest saved checkpoint details.", + it.error ) } is AsyncResult.Pending -> {} // Wait for an actual result. @@ -512,41 +529,40 @@ class ExplorationActivityPresenter @Inject constructor( private fun maybeShowSurveyDialog(profileId: ProfileId, topicId: String) { surveyGatingController.maybeShowSurvey(profileId, topicId).toLiveData() .observe( - activity, - { gatingResult -> - when (gatingResult) { - is AsyncResult.Pending -> { - oppiaLogger.d("ExplorationActivity", "A gating decision is pending") - } - is AsyncResult.Failure -> { - oppiaLogger.e( - "ExplorationActivity", - "Failed to retrieve gating decision", - gatingResult.error - ) + activity + ) { gatingResult -> + when (gatingResult) { + is AsyncResult.Pending -> { + oppiaLogger.d("ExplorationActivity", "A gating decision is pending") + } + is AsyncResult.Failure -> { + oppiaLogger.e( + "ExplorationActivity", + "Failed to retrieve gating decision", + gatingResult.error + ) + backPressActivitySelector() + } + is AsyncResult.Success -> { + if (gatingResult.value) { + val dialogFragment = + SurveyWelcomeDialogFragment.newInstance( + profileId, + topicId, + explorationId, + SURVEY_QUESTIONS + ) + val transaction = activity.supportFragmentManager.beginTransaction() + transaction + .add(dialogFragment, TAG_SURVEY_WELCOME_DIALOG) + .addToBackStack(null) + .commit() + } else { backPressActivitySelector() } - is AsyncResult.Success -> { - if (gatingResult.value) { - val dialogFragment = - SurveyWelcomeDialogFragment.newInstance( - profileId, - topicId, - explorationId, - SURVEY_QUESTIONS - ) - val transaction = activity.supportFragmentManager.beginTransaction() - transaction - .add(dialogFragment, TAG_SURVEY_WELCOME_DIALOG) - .addToBackStack(null) - .commit() - } else { - backPressActivitySelector() - } - } } } - ) + } } companion object { 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 7ec6ce8317d..2433999b826 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 @@ -65,16 +65,17 @@ class StoryFragmentPresenter @Inject constructor( private lateinit var linearSmoothScroller: RecyclerView.SmoothScroller private lateinit var profileId: ProfileId - @Inject lateinit var storyViewModel: StoryViewModel @Inject lateinit var accessibilityService: AccessibilityService + @Inject lateinit var storyViewModel: StoryViewModel + fun handleCreateView( inflater: LayoutInflater, container: ViewGroup?, internalProfileId: Int, topicId: String, storyId: String - ): View? { + ): View { binding = StoryFragmentBinding.inflate( inflater, container, @@ -89,9 +90,10 @@ class StoryFragmentPresenter @Inject constructor( binding.storyToolbar.setNavigationOnClickListener { (activity as StoryActivity).finish() } - - binding.storyToolbarTitle.setOnClickListener { - binding.storyToolbarTitle.isSelected = true + if (!accessibilityService.isScreenReaderEnabled()) { + binding.storyToolbarTitle.setOnClickListener { + binding.storyToolbarTitle.isSelected = true + } } linearLayoutManager = LinearLayoutManager(activity.applicationContext) @@ -274,11 +276,17 @@ class StoryFragmentPresenter @Inject constructor( // one. val startPlayingProvider = if (canHavePartialProgressSaved) { explorationDataController.startPlayingNewExploration( - profileId.internalId, topicId, storyId, explorationId + profileId.internalId, + topicId, + storyId, + explorationId ) } else { explorationDataController.replayExploration( - profileId.internalId, topicId, storyId, explorationId + profileId.internalId, + topicId, + storyId, + explorationId ) } startPlayingProvider.toLiveData().observe(fragment) { result -> diff --git a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt index b94b7db6029..b7bb9548635 100644 --- a/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/topic/TopicFragmentPresenter.kt @@ -20,6 +20,7 @@ import org.oppia.android.app.translation.AppLanguageResourceHandler import org.oppia.android.databinding.TopicFragmentBinding import org.oppia.android.domain.oppialogger.OppiaLogger import org.oppia.android.domain.oppialogger.analytics.AnalyticsController +import org.oppia.android.util.accessibility.AccessibilityService import org.oppia.android.util.platformparameter.EnableExtraTopicTabsUi import org.oppia.android.util.platformparameter.PlatformParameterValue import javax.inject.Inject @@ -35,6 +36,9 @@ class TopicFragmentPresenter @Inject constructor( @EnableExtraTopicTabsUi private val enableExtraTopicTabsUi: PlatformParameterValue, private val resourceHandler: AppLanguageResourceHandler ) { + @Inject + lateinit var accessibilityService: AccessibilityService + private lateinit var tabLayout: TabLayout private var internalProfileId: Int = -1 private lateinit var topicId: String @@ -48,7 +52,7 @@ class TopicFragmentPresenter @Inject constructor( topicId: String, storyId: String, isConfigChanged: Boolean - ): View? { + ): View { val binding = TopicFragmentBinding.inflate( inflater, container, @@ -64,11 +68,11 @@ class TopicFragmentPresenter @Inject constructor( binding.topicToolbar.setNavigationOnClickListener { (activity as TopicActivity).finish() } - - binding.topicToolbar.setOnClickListener { - binding.topicToolbarTitle.isSelected = true + if (!accessibilityService.isScreenReaderEnabled()) { + binding.topicToolbarTitle.setOnClickListener { + binding.topicToolbarTitle.isSelected = true + } } - viewModel.setInternalProfileId(internalProfileId) viewModel.setTopicId(topicId) binding.viewModel = viewModel @@ -152,7 +156,8 @@ class TopicFragmentPresenter @Inject constructor( TopicTab.REVISION -> oppiaLogger.createOpenRevisionTabContext(topicId) } analyticsController.logImportantEvent( - eventContext, ProfileId.newBuilder().apply { internalId = internalProfileId }.build() + eventContext, + ProfileId.newBuilder().apply { internalId = internalProfileId }.build() ) } } diff --git a/app/src/main/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityPresenter.kt b/app/src/main/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityPresenter.kt index 0a1fd1b287f..62f5b68f886 100644 --- a/app/src/main/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityPresenter.kt +++ b/app/src/main/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityPresenter.kt @@ -5,7 +5,6 @@ import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.databinding.DataBindingUtil import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import androidx.lifecycle.Transformations import org.oppia.android.R import org.oppia.android.app.activity.ActivityScope @@ -19,6 +18,7 @@ import org.oppia.android.domain.oppialogger.OppiaLogger import org.oppia.android.domain.oppialogger.analytics.AnalyticsController import org.oppia.android.domain.topic.TopicController import org.oppia.android.domain.translation.TranslationController +import org.oppia.android.util.accessibility.AccessibilityService import org.oppia.android.util.data.AsyncResult import org.oppia.android.util.data.DataProviders.Companion.toLiveData import javax.inject.Inject @@ -32,6 +32,7 @@ class RevisionCardActivityPresenter @Inject constructor( private val topicController: TopicController, private val translationController: TranslationController ) { + @Inject lateinit var accessibilityService: AccessibilityService private lateinit var revisionCardToolbar: Toolbar private lateinit var revisionCardToolbarTitle: TextView @@ -66,9 +67,12 @@ class RevisionCardActivityPresenter @Inject constructor( binding.revisionCardToolbar.setNavigationOnClickListener { (activity as ReturnToTopicClickListener).onReturnToTopicRequested() } - binding.revisionCardToolbarTitle.setOnClickListener { - binding.revisionCardToolbarTitle.isSelected = true + if (!accessibilityService.isScreenReaderEnabled()) { + binding.revisionCardToolbarTitle.setOnClickListener { + binding.revisionCardToolbarTitle.isSelected = true + } } + subscribeToSubtopicTitle() binding.actionBottomSheetOptionsMenu.setOnClickListener { @@ -89,14 +93,18 @@ class RevisionCardActivityPresenter @Inject constructor( return when (itemId) { R.id.action_options -> { val intent = OptionsActivity.createOptionsActivity( - activity, profileId.internalId, isFromNavigationDrawer = false + activity, + profileId.internalId, + isFromNavigationDrawer = false ) activity.startActivity(intent) true } R.id.action_help -> { val intent = HelpActivity.createHelpActivityIntent( - activity, profileId.internalId, isFromNavigationDrawer = false + activity, + profileId.internalId, + isFromNavigationDrawer = false ) activity.startActivity(intent) true @@ -117,11 +125,10 @@ class RevisionCardActivityPresenter @Inject constructor( private fun subscribeToSubtopicTitle() { subtopicLiveData.observe( - activity, - Observer { - revisionCardToolbarTitle.text = it - } - ) + activity + ) { + revisionCardToolbarTitle.text = it + } } private val subtopicLiveData: LiveData by lazy { @@ -143,7 +150,9 @@ class RevisionCardActivityPresenter @Inject constructor( when (revisionCardResult) { is AsyncResult.Failure -> { oppiaLogger.e( - "RevisionCardActivity", "Failed to retrieve Revision Card", revisionCardResult.error + "RevisionCardActivity", + "Failed to retrieve Revision Card", + revisionCardResult.error ) EphemeralRevisionCard.getDefaultInstance() } diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt index a8c1bea4d8c..bb97f37ed2c 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/player/exploration/ExplorationActivityTest.kt @@ -265,7 +265,9 @@ class ExplorationActivityTest { // TODO(#388): Fill in remaining tests for this activity. @get:Rule var explorationActivityTestRule: ActivityTestRule = ActivityTestRule( - ExplorationActivity::class.java, /* initialTouchMode= */ true, /* launchActivity= */ false + ExplorationActivity::class.java, /* initialTouchMode= */ + true, /* launchActivity= */ + false ) @Test @@ -325,8 +327,9 @@ class ExplorationActivityTest { } @Test - fun testExploration_toolbarTitle_marqueeInRtl_isDisplayedCorrectly() { + fun testExploration_toolbarTitle_readerOff_marqueeInRtl_isDisplayedCorrectly() { markAllSpotlightsSeen() + fakeAccessibilityService.setScreenReaderEnabled(false) explorationActivityTestRule.launchActivity( createExplorationActivityIntent( internalProfileId, @@ -342,12 +345,37 @@ class ExplorationActivityTest { onView(withId(R.id.exploration_toolbar_title)).perform(click()) assertThat(explorationToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(explorationToolbarTitle.isSelected).isEqualTo(true) assertThat(explorationToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) } @Test - fun testExploration_toolbarTitle_marqueeInLtr_isDisplayedCorrectly() { + fun testExploration_toolbarTitle_readerOn_marqueeInRtl_isDisplayedCorrectly() { markAllSpotlightsSeen() + fakeAccessibilityService.setScreenReaderEnabled(true) + explorationActivityTestRule.launchActivity( + createExplorationActivityIntent( + internalProfileId, + TEST_TOPIC_ID_0, + TEST_STORY_ID_0, + TEST_EXPLORATION_ID_2, + shouldSavePartialProgress = false + ) + ) + val explorationToolbarTitle: TextView = + explorationActivityTestRule.activity.findViewById(R.id.exploration_toolbar_title) + ViewCompat.setLayoutDirection(explorationToolbarTitle, ViewCompat.LAYOUT_DIRECTION_RTL) + + onView(withId(R.id.exploration_toolbar_title)).perform(click()) + assertThat(explorationToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(explorationToolbarTitle.isSelected).isEqualTo(false) + assertThat(explorationToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) + } + + @Test + fun testExploration_toolbarTitle_readerOff_marqueeInLtr_isDisplayedCorrectly() { + markAllSpotlightsSeen() + fakeAccessibilityService.setScreenReaderEnabled(false) explorationActivityTestRule.launchActivity( createExplorationActivityIntent( internalProfileId, @@ -362,10 +390,34 @@ class ExplorationActivityTest { ViewCompat.setLayoutDirection(explorationToolbarTitle, ViewCompat.LAYOUT_DIRECTION_LTR) onView(withId(R.id.exploration_toolbar_title)).perform(click()) + assertThat(explorationToolbarTitle.isSelected).isEqualTo(true) assertThat(explorationToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) assertThat(explorationToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) } + @Test + fun testExploration_toolbarTitle_readerOn_marqueeInLtr_isDisplayedCorrectly() { + markAllSpotlightsSeen() + fakeAccessibilityService.setScreenReaderEnabled(true) + explorationActivityTestRule.launchActivity( + createExplorationActivityIntent( + internalProfileId, + TEST_TOPIC_ID_0, + TEST_STORY_ID_0, + TEST_EXPLORATION_ID_2, + shouldSavePartialProgress = false + ) + ) + val explorationToolbarTitle: TextView = + explorationActivityTestRule.activity.findViewById(R.id.exploration_toolbar_title) + ViewCompat.setLayoutDirection(explorationToolbarTitle, ViewCompat.LAYOUT_DIRECTION_LTR) + + onView(withId(R.id.exploration_toolbar_title)).perform(click()) + assertThat(explorationToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(explorationToolbarTitle.isSelected).isEqualTo(false) + assertThat(explorationToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) + } + @Test fun testExploration_configurationChange_toolbarTitle_isDisplayedSuccessfully() { launch( @@ -801,8 +853,10 @@ class ExplorationActivityTest { setUpAudio() launch( createExplorationActivityIntent( - internalProfileId, RATIOS_TOPIC_ID, - RATIOS_STORY_ID_0, RATIOS_EXPLORATION_ID_0, + internalProfileId, + RATIOS_TOPIC_ID, + RATIOS_STORY_ID_0, + RATIOS_EXPLORATION_ID_0, shouldSavePartialProgress = false ) ).use { @@ -828,8 +882,10 @@ class ExplorationActivityTest { setUpAudio() launch( createExplorationActivityIntent( - internalProfileId, RATIOS_TOPIC_ID, - RATIOS_STORY_ID_0, RATIOS_EXPLORATION_ID_0, + internalProfileId, + RATIOS_TOPIC_ID, + RATIOS_STORY_ID_0, + RATIOS_EXPLORATION_ID_0, shouldSavePartialProgress = false ) ).use { @@ -856,8 +912,10 @@ class ExplorationActivityTest { setUpAudio() launch( createExplorationActivityIntent( - internalProfileId, RATIOS_TOPIC_ID, - RATIOS_STORY_ID_0, RATIOS_EXPLORATION_ID_0, + internalProfileId, + RATIOS_TOPIC_ID, + RATIOS_STORY_ID_0, + RATIOS_EXPLORATION_ID_0, shouldSavePartialProgress = false ) ).use { @@ -939,8 +997,10 @@ class ExplorationActivityTest { setUpAudio() launch( createExplorationActivityIntent( - internalProfileId, RATIOS_TOPIC_ID, - RATIOS_STORY_ID_0, RATIOS_EXPLORATION_ID_0, + internalProfileId, + RATIOS_TOPIC_ID, + RATIOS_STORY_ID_0, + RATIOS_EXPLORATION_ID_0, shouldSavePartialProgress = false ) ).use { @@ -980,8 +1040,10 @@ class ExplorationActivityTest { setUpAudio() launch( createExplorationActivityIntent( - internalProfileId, RATIOS_TOPIC_ID, - RATIOS_STORY_ID_0, RATIOS_EXPLORATION_ID_0, + internalProfileId, + RATIOS_TOPIC_ID, + RATIOS_STORY_ID_0, + RATIOS_EXPLORATION_ID_0, shouldSavePartialProgress = false ) ).use { @@ -1131,8 +1193,10 @@ class ExplorationActivityTest { networkConnectionUtil.setCurrentConnectionStatus(ProdConnectionStatus.LOCAL) launch( createExplorationActivityIntent( - internalProfileId, RATIOS_TOPIC_ID, - RATIOS_STORY_ID_0, RATIOS_EXPLORATION_ID_0, + internalProfileId, + RATIOS_TOPIC_ID, + RATIOS_STORY_ID_0, + RATIOS_EXPLORATION_ID_0, shouldSavePartialProgress = false ) ).use { @@ -2071,7 +2135,7 @@ class ExplorationActivityTest { internalProfileId, TEST_TOPIC_ID_0, TEST_STORY_ID_0, - TEST_EXPLORATION_ID_2, + TEST_EXPLORATION_ID_2 ) testCoroutineDispatchers.runCurrent() onView(withId(R.id.action_bottom_sheet_options_menu)).perform(click()) @@ -2131,7 +2195,7 @@ class ExplorationActivityTest { internalProfileId, TEST_TOPIC_ID_0, TEST_STORY_ID_0, - TEST_EXPLORATION_ID_2, + TEST_EXPLORATION_ID_2 ) testCoroutineDispatchers.runCurrent() onView(withId(R.id.action_bottom_sheet_options_menu)).perform(click()) @@ -2165,7 +2229,7 @@ class ExplorationActivityTest { internalProfileId, TEST_TOPIC_ID_0, TEST_STORY_ID_0, - TEST_EXPLORATION_ID_2, + TEST_EXPLORATION_ID_2 ) testCoroutineDispatchers.runCurrent() onView(withId(R.id.action_bottom_sheet_options_menu)).perform(click()) @@ -2219,7 +2283,8 @@ class ExplorationActivityTest { // Espresso can't load Robolectric into its classpath). if (isOnRobolectric()) { val dataSource = createAudioDataSource( - explorationId = RATIOS_EXPLORATION_ID_0, audioFileName = "content-en-057j51i2es.mp3" + explorationId = RATIOS_EXPLORATION_ID_0, + audioFileName = "content-en-057j51i2es.mp3" ) addShadowMediaPlayerException(dataSource!!, IOException("Test does not have networking")) } @@ -2230,10 +2295,12 @@ class ExplorationActivityTest { // Espresso can't load Robolectric into its classpath). if (isOnRobolectric()) { val dataSource = createAudioDataSource( - explorationId = FRACTIONS_EXPLORATION_ID_0, audioFileName = "content-en-nb3k4zuyir.mp3" + explorationId = FRACTIONS_EXPLORATION_ID_0, + audioFileName = "content-en-nb3k4zuyir.mp3" ) val dataSource2 = createAudioDataSource( - explorationId = FRACTIONS_EXPLORATION_ID_0, audioFileName = "content-hi-en-l8ik9pdxj2a.mp3" + explorationId = FRACTIONS_EXPLORATION_ID_0, + audioFileName = "content-hi-en-l8ik9pdxj2a.mp3" ) addShadowMediaPlayerException(dataSource!!, IOException("Test does not have networking")) addShadowMediaPlayerException(dataSource2!!, IOException("Test does not have networking")) @@ -2245,7 +2312,9 @@ class ExplorationActivityTest { val shadowMediaPlayerClass = classLoader.loadClass("org.robolectric.shadows.ShadowMediaPlayer") val addException = shadowMediaPlayerClass.getDeclaredMethod( - "addException", dataSource.javaClass, IOException::class.java + "addException", + dataSource.javaClass, + IOException::class.java ) addException.invoke(/* obj= */ null, dataSource, exception) } @@ -2261,7 +2330,9 @@ class ExplorationActivityTest { val dataSourceClass = classLoader.loadClass("org.robolectric.shadows.util.DataSource") val toDataSource = dataSourceClass.getDeclaredMethod( - "toDataSource", String::class.java, Map::class.java + "toDataSource", + String::class.java, + Map::class.java ) return toDataSource.invoke(/* obj= */ null, audioUrl, /* headers= */ null) } @@ -2426,7 +2497,6 @@ class ExplorationActivityTest { CpuPerformanceSnapshotterModule::class, ExplorationProgressModule::class ] ) - interface TestApplicationComponent : ApplicationComponent { @Component.Builder interface Builder : ApplicationComponent.Builder 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 56cf2a883ea..21202b8915d 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 @@ -186,7 +186,9 @@ class StoryFragmentTest { @get:Rule var activityTestRule: ActivityTestRule = ActivityTestRule( - StoryActivity::class.java, /* initialTouchMode= */ true, /* launchActivity= */ false + StoryActivity::class.java, /* initialTouchMode= */ + true, /* launchActivity= */ + false ) private val internalProfileId = 0 @@ -227,9 +229,27 @@ class StoryFragmentTest { } } - @Test // TODO(#4212): Error -> Only the original thread that created a view hierarchy can touch - // its view - fun testStoryFragment_toolbarTitle_marqueeInRtl_isDisplayedCorrectly() { + // TODO(#4212): Error -> Only the original thread that created a view hierarchy can touch its view + @Test + fun testStoryFragment_toolbarTitle_readerOff_marqueeInRtl_isDisplayedCorrectly() { + accessibilityService.setScreenReaderEnabled(false) + activityTestRule.launchActivity(createFractionsStoryActivityIntent()) + testCoroutineDispatchers.runCurrent() + + val storyToolbarTitle: TextView = + activityTestRule.activity.findViewById(R.id.story_toolbar_title) + ViewCompat.setLayoutDirection(storyToolbarTitle, ViewCompat.LAYOUT_DIRECTION_RTL) + + onView(withId(R.id.story_toolbar_title)).perform(click()) + assertThat(storyToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(storyToolbarTitle.isSelected).isEqualTo(true) + assertThat(storyToolbarTitle.textAlignment).isEqualTo(TEXT_ALIGNMENT_VIEW_START) + } + + // TODO(#4212): Error -> Only the original thread that created a view hierarchy can touch its view + @Test + fun testStoryFragment_toolbarTitle_readerOn_marqueeInRtl_isDisplayedCorrectly() { + accessibilityService.setScreenReaderEnabled(true) activityTestRule.launchActivity(createFractionsStoryActivityIntent()) testCoroutineDispatchers.runCurrent() @@ -239,12 +259,30 @@ class StoryFragmentTest { onView(withId(R.id.story_toolbar_title)).perform(click()) assertThat(storyToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(storyToolbarTitle.isSelected).isEqualTo(false) assertThat(storyToolbarTitle.textAlignment).isEqualTo(TEXT_ALIGNMENT_VIEW_START) } - @Test // TODO(#4212): Error -> Only the original thread that created a view hierarchy can touch - // its view - fun testStoryFragment_toolbarTitle_marqueeInLtr_isDisplayedCorrectly() { + // TODO(#4212): Error -> Only the original thread that created a view hierarchy can touch its view + @Test + fun testStoryFragment_toolbarTitle_readerOff_marqueeInLtr_isDisplayedCorrectly() { + accessibilityService.setScreenReaderEnabled(false) + activityTestRule.launchActivity(createFractionsStoryActivityIntent()) + testCoroutineDispatchers.runCurrent() + + val storyToolbarTitle: TextView = + activityTestRule.activity.findViewById(R.id.story_toolbar_title) + ViewCompat.setLayoutDirection(storyToolbarTitle, ViewCompat.LAYOUT_DIRECTION_LTR) + onView(withId(R.id.story_toolbar_title)).perform(click()) + assertThat(storyToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(storyToolbarTitle.isSelected).isEqualTo(true) + assertThat(storyToolbarTitle.textAlignment).isEqualTo(TEXT_ALIGNMENT_VIEW_START) + } + + // TODO(#4212): Error -> Only the original thread that created a view hierarchy can touch its view + @Test + fun testStoryFragment_toolbarTitle_readerOn_marqueeInLtr_isDisplayedCorrectly() { + accessibilityService.setScreenReaderEnabled(true) activityTestRule.launchActivity(createFractionsStoryActivityIntent()) testCoroutineDispatchers.runCurrent() @@ -254,6 +292,7 @@ class StoryFragmentTest { onView(withId(R.id.story_toolbar_title)).perform(click()) assertThat(storyToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(storyToolbarTitle.isSelected).isEqualTo(false) assertThat(storyToolbarTitle.textAlignment).isEqualTo(TEXT_ALIGNMENT_VIEW_START) } @@ -877,7 +916,9 @@ class StoryFragmentTest { private fun TextView.getClickableSpans(): List> { val viewText = text return (viewText as Spannable).getSpans( - /* start= */ 0, /* end= */ text.length, ClickableSpan::class.java + /* start= */ 0, /* end= */ + text.length, + ClickableSpan::class.java ).map { viewText.subSequence(viewText.getSpanStart(it), viewText.getSpanEnd(it)).toString() to it } diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt index c0a51d20a14..93dc07a0ade 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerActivityTest.kt @@ -3,8 +3,15 @@ package org.oppia.android.app.thirdparty import android.app.Application import android.content.Context import android.content.Intent +import android.text.TextUtils +import android.view.View +import android.widget.TextView import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.ViewCompat import androidx.test.core.app.ApplicationProvider +import androidx.test.espresso.Espresso +import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.matcher.ViewMatchers import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.rule.ActivityTestRule import com.google.common.truth.Truth.assertThat @@ -70,6 +77,7 @@ import org.oppia.android.testing.robolectric.RobolectricModule import org.oppia.android.testing.threading.TestDispatcherModule 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 @@ -110,6 +118,9 @@ class LicenseTextViewerActivityTest { /* launchActivity= */ false ) + @Inject + lateinit var fakeAccessibilityService: FakeAccessibilityService + @Inject lateinit var context: Context @@ -145,6 +156,90 @@ class LicenseTextViewerActivityTest { ) } + @Test + fun testExploration_toolbarTitle_readerOff_marqueeInRtl_isDisplayedCorrectly() { + fakeAccessibilityService.setScreenReaderEnabled(false) + activityTestRule.launchActivity( + createLicenseTextViewerActivityIntent( + dependencyIndex = 0, + licenseIndex = 0 + ) + ) + + val activityToolbarTitle: TextView = + activityTestRule.activity.findViewById(R.id.license_text_viewer_activity_toolbar_title) + ViewCompat.setLayoutDirection(activityToolbarTitle, ViewCompat.LAYOUT_DIRECTION_RTL) + + Espresso.onView(ViewMatchers.withId(R.id.license_text_viewer_activity_toolbar_title)) + .perform(ViewActions.click()) + assertThat(activityToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(activityToolbarTitle.isSelected).isEqualTo(true) + assertThat(activityToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) + } + + @Test + fun testExploration_toolbarTitle_readerOn_marqueeInRtl_isDisplayedCorrectly() { + fakeAccessibilityService.setScreenReaderEnabled(true) + activityTestRule.launchActivity( + createLicenseTextViewerActivityIntent( + dependencyIndex = 0, + licenseIndex = 0 + ) + ) + + val activityToolbarTitle: TextView = + activityTestRule.activity.findViewById(R.id.license_text_viewer_activity_toolbar_title) + ViewCompat.setLayoutDirection(activityToolbarTitle, ViewCompat.LAYOUT_DIRECTION_RTL) + + Espresso.onView(ViewMatchers.withId(R.id.license_text_viewer_activity_toolbar_title)) + .perform(ViewActions.click()) + assertThat(activityToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(activityToolbarTitle.isSelected).isEqualTo(false) + assertThat(activityToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) + } + + @Test + fun testExploration_toolbarTitle_readerOff_marqueeInLtr_isDisplayedCorrectly() { + fakeAccessibilityService.setScreenReaderEnabled(false) + activityTestRule.launchActivity( + createLicenseTextViewerActivityIntent( + dependencyIndex = 0, + licenseIndex = 0 + ) + ) + + val activityToolbarTitle: TextView = + activityTestRule.activity.findViewById(R.id.license_text_viewer_activity_toolbar_title) + ViewCompat.setLayoutDirection(activityToolbarTitle, ViewCompat.LAYOUT_DIRECTION_LTR) + + Espresso.onView(ViewMatchers.withId(R.id.license_text_viewer_activity_toolbar_title)) + .perform(ViewActions.click()) + assertThat(activityToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(activityToolbarTitle.isSelected).isEqualTo(true) + assertThat(activityToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) + } + + @Test + fun testExploration_toolbarTitle_readerOn_marqueeInLtr_isDisplayedCorrectly() { + fakeAccessibilityService.setScreenReaderEnabled(true) + activityTestRule.launchActivity( + createLicenseTextViewerActivityIntent( + dependencyIndex = 0, + licenseIndex = 0 + ) + ) + + val activityToolbarTitle: TextView = + activityTestRule.activity.findViewById(R.id.license_text_viewer_activity_toolbar_title) + ViewCompat.setLayoutDirection(activityToolbarTitle, ViewCompat.LAYOUT_DIRECTION_LTR) + + Espresso.onView(ViewMatchers.withId(R.id.license_text_viewer_activity_toolbar_title)) + .perform(ViewActions.click()) + assertThat(activityToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(activityToolbarTitle.isSelected).isEqualTo(false) + assertThat(activityToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) + } + private fun setUpTestApplicationComponent() { ApplicationProvider.getApplicationContext().inject(this) } @@ -191,7 +286,6 @@ class LicenseTextViewerActivityTest { CpuPerformanceSnapshotterModule::class, ExplorationProgressModule::class ] ) - interface TestApplicationComponent : ApplicationComponent { @Component.Builder diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt index b9b565bb011..333cab9044e 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/topic/TopicFragmentTest.kt @@ -105,6 +105,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 @@ -142,19 +143,36 @@ private const val REVISION_TAB_POSITION_EXTRA_TABS_DISABLED = 1 qualifiers = "port-xxhdpi" ) class TopicFragmentTest { - @get:Rule val initializeDefaultLocaleRule = InitializeDefaultLocaleRule() - @get:Rule val oppiaTestRule = OppiaTestRule() + @get:Rule + val initializeDefaultLocaleRule = InitializeDefaultLocaleRule() + + @get:Rule + val oppiaTestRule = OppiaTestRule() @get:Rule var activityTestRule: ActivityTestRule = ActivityTestRule( - TopicActivity::class.java, /* initialTouchMode= */ true, /* launchActivity= */ false + TopicActivity::class.java, /* initialTouchMode= */ + true, /* launchActivity= */ + false ) - @Inject lateinit var testCoroutineDispatchers: TestCoroutineDispatchers - @Inject lateinit var spotlightStateController: SpotlightStateController - @Inject lateinit var fakeOppiaClock: FakeOppiaClock - @Inject lateinit var storyProgressTestHelper: StoryProgressTestHelper - @Inject lateinit var fakeAnalyticsEventLogger: FakeAnalyticsEventLogger + @Inject + lateinit var testCoroutineDispatchers: TestCoroutineDispatchers + + @Inject + lateinit var spotlightStateController: SpotlightStateController + + @Inject + lateinit var fakeOppiaClock: FakeOppiaClock + + @Inject + lateinit var storyProgressTestHelper: StoryProgressTestHelper + + @Inject + lateinit var fakeAnalyticsEventLogger: FakeAnalyticsEventLogger + + @Inject + lateinit var fakeAccessibilityService: FakeAccessibilityService @field:[Inject EnableExtraTopicTabsUi] lateinit var enableExtraTopicTabsUi: PlatformParameterValue @@ -315,8 +333,10 @@ class TopicFragmentTest { } @Test - fun testTopicFragment_toolbarTitle_marqueeInRtl_isDisplayedCorrectly() { + fun testTopicFragment_toolbarTitle_readerOff_marqueeInRtl_isDisplayedCorrectly() { initializeApplicationComponent(false) + markSpotlightSeen(TOPIC_LESSON_TAB) + fakeAccessibilityService.setScreenReaderEnabled(false) activityTestRule.launchActivity( createTopicActivityIntent( internalProfileId, @@ -330,12 +350,58 @@ class TopicFragmentTest { onView(withId(R.id.topic_toolbar_title)).perform(click()) assertThat(topicToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(topicToolbarTitle.isSelected).isEqualTo(true) assertThat(topicToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) } @Test - fun testTopicFragment_toolbarTitle_marqueeInLtr_isDisplayedCorrectly() { + fun testTopicFragment_toolbarTitle_readerOn_marqueeInRtl_isDisplayedCorrectly() { initializeApplicationComponent(false) + markSpotlightSeen(TOPIC_LESSON_TAB) + fakeAccessibilityService.setScreenReaderEnabled(true) + activityTestRule.launchActivity( + createTopicActivityIntent( + internalProfileId, + FRACTIONS_TOPIC_ID + ) + ) + testCoroutineDispatchers.runCurrent() + val topicToolbarTitle: TextView = + activityTestRule.activity.findViewById(R.id.topic_toolbar_title) + ViewCompat.setLayoutDirection(topicToolbarTitle, ViewCompat.LAYOUT_DIRECTION_RTL) + + onView(withId(R.id.topic_toolbar_title)).perform(click()) + assertThat(topicToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(topicToolbarTitle.isSelected).isEqualTo(false) + assertThat(topicToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) + } + + @Test + fun testTopicFragment_toolbarTitle_readerOff_marqueeInLtr_isDisplayedCorrectly() { + initializeApplicationComponent(false) + markSpotlightSeen(TOPIC_LESSON_TAB) + fakeAccessibilityService.setScreenReaderEnabled(false) + activityTestRule.launchActivity( + createTopicActivityIntent( + internalProfileId, + FRACTIONS_TOPIC_ID + ) + ) + testCoroutineDispatchers.runCurrent() + val topicToolbarTitle: TextView = + activityTestRule.activity.findViewById(R.id.topic_toolbar_title) + ViewCompat.setLayoutDirection(topicToolbarTitle, ViewCompat.LAYOUT_DIRECTION_LTR) + onView(withId(R.id.topic_toolbar_title)).perform(click()) + assertThat(topicToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(topicToolbarTitle.isSelected).isEqualTo(true) + assertThat(topicToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) + } + + @Test + fun testTopicFragment_toolbarTitle_readerOn_marqueeInLtr_isDisplayedCorrectly() { + initializeApplicationComponent(false) + markSpotlightSeen(TOPIC_LESSON_TAB) + fakeAccessibilityService.setScreenReaderEnabled(true) activityTestRule.launchActivity( createTopicActivityIntent( internalProfileId, @@ -348,6 +414,7 @@ class TopicFragmentTest { ViewCompat.setLayoutDirection(topicToolbarTitle, ViewCompat.LAYOUT_DIRECTION_LTR) onView(withId(R.id.topic_toolbar_title)).perform(click()) assertThat(topicToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(topicToolbarTitle.isSelected).isEqualTo(false) assertThat(topicToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) } @@ -812,7 +879,9 @@ class TopicFragmentTest { */ private fun createTopicActivityIntent(internalProfileId: Int, topicId: String): Intent { return TopicActivity.createTopicActivityIntent( - ApplicationProvider.getApplicationContext(), internalProfileId, topicId + ApplicationProvider.getApplicationContext(), + internalProfileId, + topicId ) } @@ -827,7 +896,10 @@ class TopicFragmentTest { storyId: String ): Intent { return TopicActivity.createTopicPlayStoryActivityIntent( - ApplicationProvider.getApplicationContext(), internalProfileId, topicId, storyId + ApplicationProvider.getApplicationContext(), + internalProfileId, + topicId, + storyId ) } diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt index 19fff7196b7..d28d3428aa9 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/topic/revisioncard/RevisionCardActivityTest.kt @@ -11,7 +11,6 @@ import androidx.test.core.app.ActivityScenario import androidx.test.core.app.ApplicationProvider import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.pressBack -import androidx.test.espresso.action.ViewActions import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.withContentDescription @@ -93,6 +92,7 @@ import org.oppia.android.testing.threading.TestCoroutineDispatchers import org.oppia.android.testing.threading.TestDispatcherModule 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 @@ -124,14 +124,29 @@ private const val FRACTIONS_SUBTOPIC_LIST_SIZE = 4 qualifiers = "port-xxhdpi" ) class RevisionCardActivityTest { - @get:Rule val initializeDefaultLocaleRule = InitializeDefaultLocaleRule() - @get:Rule val oppiaTestRule = OppiaTestRule() + @get:Rule + val initializeDefaultLocaleRule = InitializeDefaultLocaleRule() - @Inject lateinit var context: Context - @Inject lateinit var testCoroutineDispatchers: TestCoroutineDispatchers - @Inject lateinit var translationController: TranslationController - @Inject lateinit var monitorFactory: DataProviderTestMonitor.Factory - @Inject lateinit var fakeAnalyticsEventLogger: FakeAnalyticsEventLogger + @get:Rule + val oppiaTestRule = OppiaTestRule() + + @Inject + lateinit var context: Context + + @Inject + lateinit var testCoroutineDispatchers: TestCoroutineDispatchers + + @Inject + lateinit var translationController: TranslationController + + @Inject + lateinit var monitorFactory: DataProviderTestMonitor.Factory + + @Inject + lateinit var fakeAnalyticsEventLogger: FakeAnalyticsEventLogger + + @Inject + lateinit var fakeAccessibilityService: FakeAccessibilityService private val profileId = ProfileId.newBuilder().apply { internalId = 1 }.build() @@ -149,7 +164,11 @@ class RevisionCardActivityTest { @Test fun testActivity_createIntent_verifyScreenNameInIntent() { val currentScreenName = RevisionCardActivity.createRevisionCardActivityIntent( - context, 1, FRACTIONS_TOPIC_ID, 1, FRACTIONS_SUBTOPIC_LIST_SIZE + context, + 1, + FRACTIONS_TOPIC_ID, + 1, + FRACTIONS_SUBTOPIC_LIST_SIZE ).extractCurrentAppScreenName() assertThat(currentScreenName).isEqualTo(ScreenName.REVISION_CARD_ACTIVITY) @@ -172,7 +191,30 @@ class RevisionCardActivityTest { } @Test - fun testRevisionCardActivity_toolbarTitle_marqueeInRtl_isDisplayedCorrectly() { + fun testRevisionCardActivity_toolbarTitle_readerOff_marqueeInRtl_isDisplayedCorrectly() { + fakeAccessibilityService.setScreenReaderEnabled(false) + launchRevisionCardActivity( + profileId = profileId, + topicId = FRACTIONS_TOPIC_ID, + subtopicId = 1 + ).use { scenario -> + scenario.onActivity { activity -> + + val revisionCardToolbarTitle: TextView = + activity.findViewById(R.id.revision_card_toolbar_title) + ViewCompat.setLayoutDirection(revisionCardToolbarTitle, ViewCompat.LAYOUT_DIRECTION_RTL) + + onView(withId(R.id.revision_card_toolbar_title)).perform(click()) + assertThat(revisionCardToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(revisionCardToolbarTitle.isSelected).isEqualTo(true) + assertThat(revisionCardToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) + } + } + } + + @Test + fun testRevisionCardActivity_toolbarTitle_readerOn_marqueeInRtl_isDisplayedCorrectly() { + fakeAccessibilityService.setScreenReaderEnabled(true) launchRevisionCardActivity( profileId = profileId, topicId = FRACTIONS_TOPIC_ID, @@ -184,15 +226,17 @@ class RevisionCardActivityTest { activity.findViewById(R.id.revision_card_toolbar_title) ViewCompat.setLayoutDirection(revisionCardToolbarTitle, ViewCompat.LAYOUT_DIRECTION_RTL) - onView(withId(R.id.revision_card_toolbar_title)).perform(ViewActions.click()) + onView(withId(R.id.revision_card_toolbar_title)).perform(click()) assertThat(revisionCardToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(revisionCardToolbarTitle.isSelected).isEqualTo(false) assertThat(revisionCardToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) } } } @Test - fun testRevisionCardActivity_toolbarTitle_marqueeInLtr_isDisplayedCorrectly() { + fun testRevisionCardActivity_toolbarTitle_readerOff_marqueeInLtr_isDisplayedCorrectly() { + fakeAccessibilityService.setScreenReaderEnabled(false) launchRevisionCardActivity( profileId = profileId, topicId = FRACTIONS_TOPIC_ID, @@ -206,6 +250,29 @@ class RevisionCardActivityTest { onView(withId(R.id.revision_card_toolbar_title)).perform(click()) assertThat(revisionCardToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(revisionCardToolbarTitle.isSelected).isEqualTo(true) + assertThat(revisionCardToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) + } + } + } + + @Test + fun testRevisionCardActivity_toolbarTitle_readerOn_marqueeInLtr_isDisplayedCorrectly() { + fakeAccessibilityService.setScreenReaderEnabled(true) + launchRevisionCardActivity( + profileId = profileId, + topicId = FRACTIONS_TOPIC_ID, + subtopicId = 1 + ).use { scenario -> + scenario.onActivity { activity -> + + val revisionCardToolbarTitle: TextView = + activity.findViewById(R.id.revision_card_toolbar_title) + ViewCompat.setLayoutDirection(revisionCardToolbarTitle, ViewCompat.LAYOUT_DIRECTION_LTR) + + onView(withId(R.id.revision_card_toolbar_title)).perform(click()) + assertThat(revisionCardToolbarTitle.ellipsize).isEqualTo(TextUtils.TruncateAt.MARQUEE) + assertThat(revisionCardToolbarTitle.isSelected).isEqualTo(false) assertThat(revisionCardToolbarTitle.textAlignment).isEqualTo(View.TEXT_ALIGNMENT_VIEW_START) } } @@ -367,9 +434,13 @@ class RevisionCardActivityTest { private fun createRevisionCardActivityIntent( internalProfileId: Int, topicId: String, - subtopicId: Int, + subtopicId: Int ) = RevisionCardActivity.createRevisionCardActivityIntent( - context, internalProfileId, topicId, subtopicId, FRACTIONS_SUBTOPIC_LIST_SIZE + context, + internalProfileId, + topicId, + subtopicId, + FRACTIONS_SUBTOPIC_LIST_SIZE ) private fun updateContentLanguage(profileId: ProfileId, language: OppiaLanguage) {