From f3c6dffab44079d57a8815c3ddddc3c357f556ab Mon Sep 17 00:00:00 2001 From: Subhajit Mallick <153619690+subhajitxyz@users.noreply.github.com> Date: Tue, 21 Jan 2025 19:41:53 +0530 Subject: [PATCH] Fix part of #5485: Create means for verifying Fragment Arguments (#5606) ## Explanation Fix part of #5485 Added tests for 11 fragment arguments and 'saveInstanceState'. I have not added tests for the following: 1. onSaveInstanceState of StateFragment. 2. OptionsFragment. Problems: 1. When trying to recreate StateFragment, an error occurs: "State has not been initialized." 2. In the OptionsFragmentTest class, when I try to run the test on Robolectric, it shows "No tests were found. ## 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: ...".) - [ ] 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: Sneha Datta Co-authored-by: Adhiambo Peres <59600948+adhiamboperes@users.noreply.github.com> Co-authored-by: Mr. 17 Co-authored-by: Ben Henning Co-authored-by: RD Rama Devi <122200035+Rd4dev@users.noreply.github.com> Co-authored-by: Tobiloba Oyelekan --- .../thirdparty/LicenseTextViewerFragment.kt | 3 +- .../android/app/policies/PoliciesFragment.kt | 3 +- .../AdministratorControlsFragmentTest.kt | 33 ++++++++ .../app/home/RecentlyPlayedFragmentTest.kt | 26 +++++++ .../app/options/OptionsFragmentTest.kt | 37 +++++++++ .../app/player/state/StateFragmentTest.kt | 34 ++++++++ .../app/policies/PoliciesFragmentTest.kt | 42 ++++++++++ .../ProfileProgressFragmentTest.kt | 22 ++++++ .../LicenseTextViewerFragmentTest.kt | 34 ++++++++ .../app/topic/info/TopicInfoFragmentTest.kt | 61 +++++++++++++++ .../topic/lessons/TopicLessonsFragmentTest.kt | 78 +++++++++++++++++++ .../practice/TopicPracticeFragmentTest.kt | 74 ++++++++++++++++++ .../revision/TopicRevisionFragmentTest.kt | 37 +++++++++ .../WalkthroughFinalFragmentTest.kt | 32 ++++++++ .../testing/options/OptionsFragmentTest.kt | 39 ++++++++++ 15 files changed, 552 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/oppia/android/app/help/thirdparty/LicenseTextViewerFragment.kt b/app/src/main/java/org/oppia/android/app/help/thirdparty/LicenseTextViewerFragment.kt index 64d3585b5a5..3e8a5dc9dce 100644 --- a/app/src/main/java/org/oppia/android/app/help/thirdparty/LicenseTextViewerFragment.kt +++ b/app/src/main/java/org/oppia/android/app/help/thirdparty/LicenseTextViewerFragment.kt @@ -19,8 +19,7 @@ class LicenseTextViewerFragment : InjectableFragment() { companion object { /** Argument key for LicenseTextViewerFragment. */ - private const val LICENSE_TEXT_VIEWER_FRAGMENT_ARGUMENTS_KEY = - "LicenseTextViewerFragment.arguments" + const val LICENSE_TEXT_VIEWER_FRAGMENT_ARGUMENTS_KEY = "LicenseTextViewerFragment.arguments" /** Returns an instance of [LicenseTextViewerFragment]. */ fun newInstance(dependencyIndex: Int, licenseIndex: Int): LicenseTextViewerFragment { diff --git a/app/src/main/java/org/oppia/android/app/policies/PoliciesFragment.kt b/app/src/main/java/org/oppia/android/app/policies/PoliciesFragment.kt index 06cd8bf8b67..44a2111579f 100644 --- a/app/src/main/java/org/oppia/android/app/policies/PoliciesFragment.kt +++ b/app/src/main/java/org/oppia/android/app/policies/PoliciesFragment.kt @@ -12,7 +12,8 @@ import org.oppia.android.util.extensions.getProto import org.oppia.android.util.extensions.putProto import javax.inject.Inject -private const val POLICIES_FRAGMENT_POLICY_PAGE_ARGUMENT_PROTO = "PoliciesFragment.policy_page" +/** Argument key for PoliciesFragment. */ +const val POLICIES_FRAGMENT_POLICY_PAGE_ARGUMENT_PROTO = "PoliciesFragment.policy_page" /** Fragment that contains policies flow of the app. */ class PoliciesFragment : InjectableFragment() { diff --git a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt index 6d543ac59af..71ad148b0f2 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/administratorcontrols/AdministratorControlsFragmentTest.kt @@ -8,6 +8,7 @@ import android.view.ViewParent import android.widget.FrameLayout import androidx.appcompat.app.AppCompatActivity import androidx.core.widget.NestedScrollView +import androidx.drawerlayout.widget.DrawerLayout import androidx.test.core.app.ActivityScenario.launch import androidx.test.core.app.ApplicationProvider import androidx.test.espresso.Espresso.onView @@ -23,6 +24,7 @@ import androidx.test.espresso.matcher.ViewMatchers.isClickable import androidx.test.espresso.matcher.ViewMatchers.isRoot import androidx.test.espresso.util.HumanReadables import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat import dagger.Component import org.hamcrest.Matcher import org.hamcrest.Matchers @@ -44,6 +46,7 @@ import org.oppia.android.app.application.ApplicationStartupListenerModule import org.oppia.android.app.application.testing.TestingBuildFlavorModule import org.oppia.android.app.devoptions.DeveloperOptionsModule import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule +import org.oppia.android.app.model.AdministratorControlsFragmentArguments import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPositionOnView import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.scrollToPosition @@ -98,6 +101,7 @@ import org.oppia.android.testing.time.FakeOppiaClockModule import org.oppia.android.util.accessibility.AccessibilityTestModule import org.oppia.android.util.caching.AssetModule import org.oppia.android.util.caching.testing.CachingTestModule +import org.oppia.android.util.extensions.getProto import org.oppia.android.util.gcsresource.GcsResourceModule import org.oppia.android.util.locale.LocaleProdModule import org.oppia.android.util.logging.LoggerModule @@ -433,6 +437,35 @@ class AdministratorControlsFragmentTest { } } + @Test + fun testFragment_argumentsAreCorrect() { + launch( + createAdministratorControlsFragmentTestActivityIntent( + profileId = internalProfileId + ) + ).use { scenario -> + testCoroutineDispatchers.runCurrent() + scenario.onActivity { activity -> + + val administratorControlsFragment = activity.supportFragmentManager + .findFragmentById(R.id.administrator_controls_fragment_test_activity_fragment_container) + as AdministratorControlsFragment + val isMultipane = activity + .findViewById(R.id.administrator_controls_activity_drawer_layout) != null + + val arguments = checkNotNull(administratorControlsFragment.arguments) { + "Expected arguments to be passed to AdministratorControlsFragment" + }.getProto( + ADMINISTRATOR_CONTROLS_FRAGMENT_ARGUMENTS_KEY, + AdministratorControlsFragmentArguments.getDefaultInstance() + ) + val receivedIsMultipane = arguments.isMultipane + + assertThat(receivedIsMultipane).isEqualTo(isMultipane) + } + } + } + private fun clickAutoUpdateTopicContainer() { onView( atPositionOnView( diff --git a/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt index 0916c25d749..b1a9e948d59 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/home/RecentlyPlayedFragmentTest.kt @@ -131,6 +131,7 @@ import org.oppia.android.util.networking.NetworkConnectionDebugUtilModule import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule import org.oppia.android.util.parser.image.ImageParsingModule +import org.oppia.android.util.profile.CurrentUserProfileIdIntentDecorator.extractCurrentUserProfileId import org.robolectric.annotation.Config import org.robolectric.annotation.LooperMode import javax.inject.Inject @@ -1649,6 +1650,31 @@ class RecentlyPlayedFragmentTest { } } + @Test + fun testFragment_argumentsAreCorrect() { + ActivityScenario.launch( + createRecentlyPlayedActivityIntent( + internalProfileId = internalProfileId, + RecentlyPlayedActivityTitle.STORIES_FOR_YOU + ) + ).use { scenario -> + testCoroutineDispatchers.runCurrent() + scenario.onActivity { activity -> + + val recentlyPlayedFragment = activity.supportFragmentManager + .findFragmentById(R.id.recently_played_fragment_placeholder) as RecentlyPlayedFragment + + val arguments = checkNotNull(recentlyPlayedFragment.arguments) { + "Expected arguments to be passed to RecentlyPlayedFragment" + } + val profileId = arguments.extractCurrentUserProfileId() + val receivedInternalProfileId = profileId.internalId + + assertThat(receivedInternalProfileId).isEqualTo(internalProfileId) + } + } + } + private fun setUpTestFragment(activity: RecentlyPlayedActivity) { activity.supportFragmentManager .beginTransaction() diff --git a/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt index f7abd23fcc6..aefc561573a 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/options/OptionsFragmentTest.kt @@ -3,6 +3,7 @@ package org.oppia.android.app.options import android.app.Application import android.content.Context import android.content.Intent +import android.widget.FrameLayout import androidx.appcompat.app.AppCompatActivity import androidx.drawerlayout.widget.DrawerLayout import androidx.test.core.app.ActivityScenario @@ -21,6 +22,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat import dagger.Component import org.hamcrest.Matchers.allOf import org.junit.After @@ -44,6 +46,7 @@ import org.oppia.android.app.model.AppLanguageActivityParams import org.oppia.android.app.model.AudioLanguage import org.oppia.android.app.model.AudioLanguageActivityParams import org.oppia.android.app.model.OppiaLanguage +import org.oppia.android.app.model.OptionsFragmentArguments import org.oppia.android.app.model.ProfileId import org.oppia.android.app.model.ReadingTextSize import org.oppia.android.app.model.ReadingTextSizeActivityParams @@ -99,6 +102,7 @@ import org.oppia.android.testing.time.FakeOppiaClockModule import org.oppia.android.util.accessibility.AccessibilityTestModule import org.oppia.android.util.caching.AssetModule import org.oppia.android.util.caching.testing.CachingTestModule +import org.oppia.android.util.extensions.getProto import org.oppia.android.util.gcsresource.GcsResourceModule import org.oppia.android.util.locale.LocaleProdModule import org.oppia.android.util.logging.LoggerModule @@ -559,6 +563,39 @@ class OptionsFragmentTest { } } + @Test + fun testFragment_argumentsAreCorrect() { + launch( + createOptionActivityIntent( + internalProfileId = 0, + isFromNavigationDrawer = true + ) + ).use { scenario -> + testCoroutineDispatchers.runCurrent() + scenario.onActivity { activity -> + + val optionsFragment = activity.supportFragmentManager + .findFragmentById(R.id.options_fragment_placeholder) as OptionsFragment + + val args = optionsFragment.arguments?.getProto( + OPTIONS_FRAGMENT_ARGUMENTS_KEY, + OptionsFragmentArguments.getDefaultInstance() + ) + + val isMultipane = + activity.findViewById(R.id.multipane_options_container) != null + + val receivedIsMultipane = args?.isMultipane + val receivedIsFirstOpen = args?.isFirstOpen + val receivedSelectedFragment = checkNotNull(args?.selectedFragment) + + assertThat(receivedIsMultipane).isEqualTo(isMultipane) + assertThat(receivedIsFirstOpen).isEqualTo(true) + assertThat(receivedSelectedFragment).isEqualTo(READING_TEXT_SIZE_FRAGMENT) + } + } + } + private fun rotateToLandscape() { onView(isRoot()).perform(orientationLandscape()) testCoroutineDispatchers.runCurrent() diff --git a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt index 09baf65b707..5f436a48dc7 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/player/state/StateFragmentTest.kt @@ -80,6 +80,7 @@ import org.oppia.android.app.devoptions.DeveloperOptionsModule import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule import org.oppia.android.app.model.OppiaLanguage import org.oppia.android.app.model.ProfileId +import org.oppia.android.app.model.StateFragmentArguments import org.oppia.android.app.model.WrittenTranslationLanguageSelection import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule import org.oppia.android.app.player.state.itemviewmodel.StateItemViewModel @@ -178,6 +179,7 @@ import org.oppia.android.util.accessibility.AccessibilityTestModule import org.oppia.android.util.caching.AssetModule import org.oppia.android.util.caching.LoadImagesFromAssets import org.oppia.android.util.caching.LoadLessonProtosFromAssets +import org.oppia.android.util.extensions.getProto import org.oppia.android.util.gcsresource.GcsResourceModule import org.oppia.android.util.locale.LocaleProdModule import org.oppia.android.util.logging.LoggerModule @@ -5238,6 +5240,38 @@ class StateFragmentTest { } } + @Test + fun testFragment_argumentsAreCorrect() { + setUpTestWithLanguageSwitchingFeatureOff() + launchForExploration( + FRACTIONS_EXPLORATION_ID_1, + shouldSavePartialProgress = false + ).use { scenario -> + startPlayingExploration() + + scenario.onActivity { activity -> + val stateFragment = activity.supportFragmentManager + .findFragmentById(R.id.state_fragment_placeholder) as StateFragment + + val args = + stateFragment.arguments?.getProto( + StateFragment.STATE_FRAGMENT_ARGUMENTS_KEY, + StateFragmentArguments.getDefaultInstance() + ) + + val receivedInternalProfileId = args?.internalProfileId ?: -1 + val receivedTopicId = args?.topicId!! + val receivedStoryId = args.storyId!! + val reveivedExplorationId = args.explorationId!! + + assertThat(receivedInternalProfileId).isEqualTo(profileId.internalId) + assertThat(receivedTopicId).isEqualTo(TEST_TOPIC_ID_0) + assertThat(receivedStoryId).isEqualTo(TEST_STORY_ID_0) + assertThat(reveivedExplorationId).isEqualTo(FRACTIONS_EXPLORATION_ID_1) + } + } + } + private fun playThroughRatioExplorationState1() { clickContinueInteractionButton() } diff --git a/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt index 3db8bca24cd..3e94869a44a 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/policies/PoliciesFragmentTest.kt @@ -52,6 +52,8 @@ import org.oppia.android.app.application.ApplicationStartupListenerModule import org.oppia.android.app.application.testing.TestingBuildFlavorModule import org.oppia.android.app.devoptions.DeveloperOptionsModule import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule +import org.oppia.android.app.model.PoliciesActivityParams +import org.oppia.android.app.model.PoliciesFragmentArguments import org.oppia.android.app.model.PolicyPage import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule import org.oppia.android.app.shim.ViewBindingShimModule @@ -101,6 +103,8 @@ import org.oppia.android.testing.time.FakeOppiaClockModule import org.oppia.android.util.accessibility.AccessibilityTestModule import org.oppia.android.util.caching.AssetModule import org.oppia.android.util.caching.testing.CachingTestModule +import org.oppia.android.util.extensions.getProto +import org.oppia.android.util.extensions.getProtoExtra import org.oppia.android.util.gcsresource.DefaultResourceBucketName import org.oppia.android.util.gcsresource.GcsResourceModule import org.oppia.android.util.locale.LocaleProdModule @@ -324,6 +328,44 @@ class PoliciesFragmentTest { } } + @Test + fun testFragment_argumentsAreCorrect() { + launch( + createPoliciesFragmentTestIntent( + getApplicationContext(), + PolicyPage.TERMS_OF_SERVICE + ) + ).use { scenario -> + testCoroutineDispatchers.runCurrent() + scenario.onActivity { activity -> + + val policiesFragment = activity.supportFragmentManager + .findFragmentById(R.id.policies_fragment_placeholder) as PoliciesFragment + + val policiesActivityParams = activity.intent.getProtoExtra( + PoliciesFragmentTestActivity.POLICIES_FRAGMENT_TEST_POLICY_PAGE_PARAMS_PROTO, + PoliciesActivityParams.getDefaultInstance() + ) + val policiesFragmentArguments = + PoliciesFragmentArguments + .newBuilder() + .setPolicyPage(policiesActivityParams.policyPage) + .build() + + val args = checkNotNull(policiesFragment.arguments) { + "Expected arguments to be passed to PoliciesFragment" + } + val receivedPolicies = + args.getProto( + POLICIES_FRAGMENT_POLICY_PAGE_ARGUMENT_PROTO, + PoliciesFragmentArguments.getDefaultInstance() + ) + + assertThat(receivedPolicies.policyPage).isEqualTo(policiesFragmentArguments.policyPage) + } + } + } + private fun setUpTestApplicationComponent() { getApplicationContext().inject(this) } diff --git a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt index 1bfc769e383..dd3d4d3e0de 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/profileprogress/ProfileProgressFragmentTest.kt @@ -133,6 +133,7 @@ import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule import org.oppia.android.util.parser.image.GlideImageLoaderModule import org.oppia.android.util.parser.image.ImageParsingModule +import org.oppia.android.util.profile.CurrentUserProfileIdIntentDecorator.extractCurrentUserProfileId import org.oppia.android.util.profile.PROFILE_ID_INTENT_DECORATOR import org.robolectric.annotation.Config import org.robolectric.annotation.LooperMode @@ -825,6 +826,27 @@ class ProfileProgressFragmentTest { } } + @Test + fun testFragment_argumentsAreCorrect() { + launch( + createProfileProgressActivityIntent(internalProfileId) + ).use { scenario -> + testCoroutineDispatchers.runCurrent() + scenario.onActivity { activity -> + + val profileProgressFragment = activity.supportFragmentManager + .findFragmentById(R.id.profile_progress_fragment_placeholder) as ProfileProgressFragment + + val args = checkNotNull(profileProgressFragment.arguments) { + "Expected arguments to be passed to ProfileProgressFragment" + } + val receivedInternalProfileId = args.extractCurrentUserProfileId().internalId + + assertThat(receivedInternalProfileId).isEqualTo(internalProfileId) + } + } + } + private fun createGalleryPickActivityResultStub(): Instrumentation.ActivityResult { val resources: Resources = context.resources val imageUri = Uri.parse( diff --git a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt index f264a3cc398..21608551c08 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/thirdparty/LicenseTextViewerFragmentTest.kt @@ -12,6 +12,7 @@ import androidx.test.espresso.matcher.ViewMatchers.isRoot import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat import dagger.Component import org.junit.After import org.junit.Before @@ -31,6 +32,8 @@ import org.oppia.android.app.application.testing.TestingBuildFlavorModule import org.oppia.android.app.devoptions.DeveloperOptionsModule import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule import org.oppia.android.app.help.thirdparty.LicenseTextViewerActivity +import org.oppia.android.app.help.thirdparty.LicenseTextViewerFragment +import org.oppia.android.app.model.LicenseTextViewerFragmentArguments import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule import org.oppia.android.app.shim.ViewBindingShimModule import org.oppia.android.app.translation.testing.ActivityRecreatorTestModule @@ -77,6 +80,7 @@ import org.oppia.android.testing.time.FakeOppiaClockModule import org.oppia.android.util.accessibility.AccessibilityTestModule import org.oppia.android.util.caching.AssetModule import org.oppia.android.util.caching.testing.CachingTestModule +import org.oppia.android.util.extensions.getProto import org.oppia.android.util.gcsresource.GcsResourceModule import org.oppia.android.util.locale.LocaleProdModule import org.oppia.android.util.logging.LoggerModule @@ -316,6 +320,36 @@ class LicenseTextViewerFragmentTest { } } + @Test + fun testFragment_argumentsAreCorrect() { + launch( + createLicenseTextViewerActivity( + dependencyIndex = 3, + licenseIndex = 1 + ) + ).use { scenario -> + testCoroutineDispatchers.runCurrent() + scenario.onActivity { activity -> + + val licenseTextViewerFragment = activity.supportFragmentManager + .findFragmentById(R.id.license_text_viewer_fragment_placeholder) + as LicenseTextViewerFragment + val arguments = checkNotNull(licenseTextViewerFragment.arguments) { + "Expected arguments to be passed to LicenseTextViewerFragment" + } + val args = arguments.getProto( + LicenseTextViewerFragment.LICENSE_TEXT_VIEWER_FRAGMENT_ARGUMENTS_KEY, + LicenseTextViewerFragmentArguments.getDefaultInstance() + ) + val receivedDependencyIndex = args.dependencyIndex + val receivedLicenseIndex = args.licenseIndex + + assertThat(receivedDependencyIndex).isEqualTo(3) + assertThat(receivedLicenseIndex).isEqualTo(1) + } + } + } + private fun createLicenseTextViewerActivity(dependencyIndex: Int, licenseIndex: Int): Intent { return LicenseTextViewerActivity.createLicenseTextViewerActivityIntent( ApplicationProvider.getApplicationContext(), diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt index 6af4d3d4a4f..e4550bf1fcf 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/topic/info/TopicInfoFragmentTest.kt @@ -23,11 +23,13 @@ import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.rule.ActivityTestRule +import androidx.viewpager2.widget.ViewPager2 import com.google.common.truth.Truth.assertThat import dagger.Component import org.hamcrest.CoreMatchers import org.hamcrest.Description import org.hamcrest.Matcher +import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.containsString import org.hamcrest.TypeSafeMatcher import org.junit.After @@ -48,10 +50,13 @@ import org.oppia.android.app.application.testing.TestingBuildFlavorModule import org.oppia.android.app.devoptions.DeveloperOptionsModule import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule import org.oppia.android.app.model.ProfileId +import org.oppia.android.app.model.TopicInfoFragmentArguments import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule import org.oppia.android.app.shim.ViewBindingShimModule import org.oppia.android.app.topic.TopicActivity import org.oppia.android.app.topic.TopicActivity.Companion.createTopicActivityIntent +import org.oppia.android.app.topic.TopicFragment +import org.oppia.android.app.topic.TopicTab import org.oppia.android.app.translation.testing.ActivityRecreatorTestModule import org.oppia.android.app.utility.EspressoTestsMatchers.withDrawable import org.oppia.android.app.utility.OrientationChangeAction.Companion.orientationLandscape @@ -102,6 +107,7 @@ import org.oppia.android.testing.time.FakeOppiaClockModule import org.oppia.android.util.accessibility.AccessibilityTestModule import org.oppia.android.util.caching.AssetModule import org.oppia.android.util.caching.testing.CachingTestModule +import org.oppia.android.util.extensions.getProto import org.oppia.android.util.gcsresource.GcsResourceModule import org.oppia.android.util.locale.LocaleProdModule import org.oppia.android.util.logging.LoggerModule @@ -111,6 +117,9 @@ import org.oppia.android.util.networking.NetworkConnectionDebugUtilModule import org.oppia.android.util.networking.NetworkConnectionUtilDebugModule import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule import org.oppia.android.util.parser.image.ImageParsingModule +import org.oppia.android.util.platformparameter.EnableExtraTopicTabsUi +import org.oppia.android.util.platformparameter.PlatformParameterValue +import org.oppia.android.util.profile.CurrentUserProfileIdIntentDecorator.extractCurrentUserProfileId import org.robolectric.annotation.Config import org.robolectric.annotation.LooperMode import javax.inject.Inject @@ -154,6 +163,9 @@ class TopicInfoFragmentTest { @Inject lateinit var testCoroutineDispatchers: TestCoroutineDispatchers + @field:[Inject EnableExtraTopicTabsUi] + lateinit var enableExtraTopicTabsUi: PlatformParameterValue + @get:Rule var activityTestRule: ActivityTestRule = ActivityTestRule( TopicActivity::class.java, /* initialTouchMode= */ true, /* launchActivity= */ false @@ -439,6 +451,40 @@ class TopicInfoFragmentTest { } } + @Test + fun testFragment_argumentsAreCorrect() { + launchTopicActivityIntent( + profileId = profileId, + classroomId = TEST_CLASSROOM_ID, + topicId = TEST_TOPIC_ID + ).use { scenario -> + clickInfoTab() + testCoroutineDispatchers.runCurrent() + scenario.onActivity { activity -> + + val topicFragment = activity.supportFragmentManager + .findFragmentById(R.id.topic_fragment_placeholder) as TopicFragment + val viewPager = topicFragment.requireView() + .findViewById(R.id.topic_tabs_viewpager) + val topicInfoFragment = topicFragment.childFragmentManager + .findFragmentByTag("f${viewPager.currentItem}") as TopicInfoFragment + + val args = topicInfoFragment.arguments?.getProto( + TopicInfoFragment.TOPIC_INFO_FRAGMENT_ARGUMENTS_KEY, + TopicInfoFragmentArguments.getDefaultInstance() + ) + val receivedInternalProfileId = topicInfoFragment + .arguments?.extractCurrentUserProfileId()?.internalId ?: -1 + val receivedTopicId = checkNotNull(args?.topicId) { + "Expected topic ID to be included in arguments for TopicInfoFragment." + } + + assertThat(receivedInternalProfileId).isEqualTo(profileId.internalId) + assertThat(receivedTopicId).isEqualTo(TEST_TOPIC_ID) + } + } + } + private fun launchTopicActivityIntent( profileId: ProfileId, classroomId: String, @@ -454,6 +500,21 @@ class TopicInfoFragmentTest { return ActivityScenario.launch(intent) } + private fun clickInfoTab() { + onView( + allOf( + withText( + TopicTab.getTabForPosition( + position = 0, + enableExtraTopicTabsUi = enableExtraTopicTabsUi.value + ).name + ), + ViewMatchers.isDescendantOfA(withId(R.id.topic_tabs_container)) + ) + ).perform(click()) + testCoroutineDispatchers.runCurrent() + } + /** Custom function to set dummy text in the TextView. */ private fun setTextInTextView(value: String): ViewAction { return object : ViewAction { diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt index 9ceba1db737..e54dea276a9 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/topic/lessons/TopicLessonsFragmentTest.kt @@ -26,6 +26,8 @@ import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.viewpager2.widget.ViewPager2 +import com.google.common.truth.Truth.assertThat import dagger.Component import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.containsString @@ -55,6 +57,7 @@ import org.oppia.android.app.model.Spotlight.FeatureCase.FIRST_CHAPTER import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_LESSON_TAB import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_REVISION_TAB import org.oppia.android.app.model.StoryActivityParams +import org.oppia.android.app.model.TopicLessonsFragmentArguments import org.oppia.android.app.player.exploration.ExplorationActivity import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPosition @@ -64,6 +67,7 @@ import org.oppia.android.app.shim.ViewBindingShimModule import org.oppia.android.app.story.StoryActivity import org.oppia.android.app.story.StoryActivity.Companion.STORY_ACTIVITY_PARAMS_KEY import org.oppia.android.app.topic.TopicActivity +import org.oppia.android.app.topic.TopicFragment import org.oppia.android.app.topic.TopicTab import org.oppia.android.app.translation.testing.ActivityRecreatorTestModule import org.oppia.android.app.utility.EspressoTestsMatchers.hasProtoExtra @@ -124,6 +128,7 @@ 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.extensions.getProto import org.oppia.android.util.gcsresource.GcsResourceModule import org.oppia.android.util.locale.LocaleProdModule import org.oppia.android.util.logging.LoggerModule @@ -136,6 +141,7 @@ import org.oppia.android.util.parser.image.GlideImageLoaderModule import org.oppia.android.util.parser.image.ImageParsingModule import org.oppia.android.util.platformparameter.EnableExtraTopicTabsUi import org.oppia.android.util.platformparameter.PlatformParameterValue +import org.oppia.android.util.profile.CurrentUserProfileIdIntentDecorator.extractCurrentUserProfileId import org.robolectric.annotation.Config import org.robolectric.annotation.LooperMode import javax.inject.Inject @@ -1203,6 +1209,78 @@ class TopicLessonsFragmentTest { } } + @Test + fun testFragment_argumentsAreCorrect() { + launch( + createTopicPlayStoryActivityIntent( + profileId, + TEST_CLASSROOM_ID_1, + RATIOS_TOPIC_ID, + RATIOS_STORY_ID_0 + ) + ).use { scenario -> + clickLessonTab() + testCoroutineDispatchers.runCurrent() + scenario.onActivity { activity -> + + val topicFragment = activity.supportFragmentManager + .findFragmentById(R.id.topic_fragment_placeholder) as TopicFragment + val viewPager = topicFragment.requireView() + .findViewById(R.id.topic_tabs_viewpager) + val topicLessonsFragment = topicFragment.childFragmentManager + .findFragmentByTag("f${viewPager.currentItem}") as TopicLessonsFragment + + val receivedInternalProfileId = topicLessonsFragment + .arguments?.extractCurrentUserProfileId()?.internalId ?: -1 + val args = topicLessonsFragment.arguments?.getProto( + TopicLessonsFragment.TOPIC_LESSONS_FRAGMENT_ARGUMENTS_KEY, + TopicLessonsFragmentArguments.getDefaultInstance() + ) + val receivedClassroomId = checkNotNull(args?.classroomId) { + "Expected classroom ID to be included in arguments for TopicLessonsFragment." + } + val receivedTopicId = checkNotNull(args?.topicId) { + "Expected topic ID to be included in arguments for TopicLessonsFragment." + } + val receivedStoryId = args?.storyId ?: "" + + assertThat(receivedInternalProfileId).isEqualTo(profileId.internalId) + assertThat(receivedClassroomId).isEqualTo(TEST_CLASSROOM_ID_1) + assertThat(receivedTopicId).isEqualTo(RATIOS_TOPIC_ID) + assertThat(receivedStoryId).isEqualTo(RATIOS_STORY_ID_0) + } + } + } + + @Test + fun testTopicLessonsFragment_saveInstanceState_verifyCorrectStateRestored() { + launch( + createTopicPlayStoryActivityIntent( + profileId, + TEST_CLASSROOM_ID_1, + RATIOS_TOPIC_ID, + RATIOS_STORY_ID_0 + ) + ).use { scenario -> + clickLessonTab() + testCoroutineDispatchers.runCurrent() + + scrollToPosition(position = 2) + clickStoryItem(position = 2, targetViewId = R.id.chapter_list_drop_down_icon) + + scenario.recreate() + + scrollToPosition(position = 2) + onView( + atPositionOnView( + recyclerViewId = R.id.story_summary_recycler_view, + position = 2, + targetViewId = R.id.chapter_recycler_view + ) + ).check(matches(isDisplayed())) + } + } + private fun markAllSpotlightsSeen() { spotlightStateController.markSpotlightViewed(profileId, TOPIC_LESSON_TAB) testCoroutineDispatchers.runCurrent() diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt index 94fa885b5f3..8916ec5acbd 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/topic/practice/TopicPracticeFragmentTest.kt @@ -20,6 +20,8 @@ import androidx.test.espresso.matcher.ViewMatchers.isRoot import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.viewpager2.widget.ViewPager2 +import com.google.common.truth.Truth.assertThat import dagger.Component import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.not @@ -45,10 +47,12 @@ import org.oppia.android.app.model.QuestionPlayerActivityParams import org.oppia.android.app.model.Spotlight.FeatureCase.FIRST_CHAPTER import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_LESSON_TAB import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_REVISION_TAB +import org.oppia.android.app.model.TopicPracticeFragmentArguments import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPositionOnView import org.oppia.android.app.shim.ViewBindingShimModule import org.oppia.android.app.topic.TopicActivity +import org.oppia.android.app.topic.TopicFragment import org.oppia.android.app.topic.TopicTab import org.oppia.android.app.topic.questionplayer.QuestionPlayerActivity import org.oppia.android.app.topic.questionplayer.QuestionPlayerActivity.Companion.QUESTION_PLAYER_ACTIVITY_PARAMS_KEY @@ -100,6 +104,7 @@ import org.oppia.android.testing.time.FakeOppiaClockModule import org.oppia.android.util.accessibility.AccessibilityTestModule import org.oppia.android.util.caching.AssetModule import org.oppia.android.util.caching.testing.CachingTestModule +import org.oppia.android.util.extensions.getProto import org.oppia.android.util.gcsresource.GcsResourceModule import org.oppia.android.util.locale.LocaleProdModule import org.oppia.android.util.logging.LoggerModule @@ -112,6 +117,7 @@ import org.oppia.android.util.parser.image.GlideImageLoaderModule import org.oppia.android.util.parser.image.ImageParsingModule import org.oppia.android.util.platformparameter.EnableExtraTopicTabsUi import org.oppia.android.util.platformparameter.PlatformParameterValue +import org.oppia.android.util.profile.CurrentUserProfileIdIntentDecorator.extractCurrentUserProfileId import org.robolectric.annotation.Config import org.robolectric.annotation.LooperMode import javax.inject.Inject @@ -382,6 +388,74 @@ class TopicPracticeFragmentTest { } } + @Test + fun testFragment_argumentsAreCorrect() { + launchTopicActivityIntent( + profileId = profileId, + classroomId = TEST_CLASSROOM_ID_1, + topicId = FRACTIONS_TOPIC_ID + ).use { scenario -> + clickPracticeTab() + testCoroutineDispatchers.runCurrent() + scenario.onActivity { activity -> + + val topicFragment = activity.supportFragmentManager + .findFragmentById(R.id.topic_fragment_placeholder) as TopicFragment + val viewPager = topicFragment.requireView() + .findViewById(R.id.topic_tabs_viewpager) + val topicPracticeFragment = topicFragment.childFragmentManager + .findFragmentByTag("f${viewPager.currentItem}") as TopicPracticeFragment + + val args = topicPracticeFragment.arguments?.getProto( + TopicPracticeFragment.TOPIC_PRACTICE_FRAGMENT_ARGUMENTS_KEY, + TopicPracticeFragmentArguments.getDefaultInstance() + ) + val receivedInternalProfileId = topicPracticeFragment + .arguments?.extractCurrentUserProfileId()?.internalId ?: -1 + val receivedTopicId = checkNotNull(args?.topicId) { + "Expected topic ID to be included in arguments for TopicPracticeFragment." + } + + assertThat(receivedInternalProfileId).isEqualTo(profileId.internalId) + assertThat(receivedTopicId).isEqualTo(FRACTIONS_TOPIC_ID) + } + } + } + + @Test + fun testTopicPracticeFragment_saveInstanceState_verifyCorrectStateRestored() { + launchTopicActivityIntent( + profileId = profileId, + classroomId = TEST_CLASSROOM_ID_1, + topicId = FRACTIONS_TOPIC_ID + ).use { scenario -> + clickPracticeTab() + testCoroutineDispatchers.runCurrent() + + clickPracticeItem(position = 1, targetViewId = R.id.subtopic_check_box) + clickPracticeItem(position = 2, targetViewId = R.id.subtopic_check_box) + + scenario.recreate() + + scrollToPosition(position = 1) + onView( + atPositionOnView( + recyclerViewId = R.id.topic_practice_skill_list, + position = 1, + targetViewId = R.id.subtopic_check_box + ) + ).check(matches(isChecked())) + scrollToPosition(position = 2) + onView( + atPositionOnView( + recyclerViewId = R.id.topic_practice_skill_list, + position = 2, + targetViewId = R.id.subtopic_check_box + ) + ).check(matches(isChecked())) + } + } + private fun launchTopicActivityIntent( profileId: ProfileId, classroomId: String, diff --git a/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt index 2b86bba92c9..d437b8feb3d 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/topic/revision/TopicRevisionFragmentTest.kt @@ -22,6 +22,8 @@ import androidx.test.espresso.matcher.ViewMatchers.isRoot import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.viewpager2.widget.ViewPager2 +import com.google.common.truth.Truth.assertThat import dagger.Component import org.hamcrest.Matchers.allOf import org.junit.After @@ -45,11 +47,13 @@ import org.oppia.android.app.model.ProfileId import org.oppia.android.app.model.Spotlight.FeatureCase.FIRST_CHAPTER import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_LESSON_TAB import org.oppia.android.app.model.Spotlight.FeatureCase.TOPIC_REVISION_TAB +import org.oppia.android.app.model.TopicRevisionFragmentArguments import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPosition import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPositionOnView import org.oppia.android.app.shim.ViewBindingShimModule import org.oppia.android.app.topic.TopicActivity +import org.oppia.android.app.topic.TopicFragment import org.oppia.android.app.topic.TopicTab import org.oppia.android.app.topic.revisioncard.RevisionCardActivity import org.oppia.android.app.translation.testing.ActivityRecreatorTestModule @@ -102,6 +106,7 @@ import org.oppia.android.testing.time.FakeOppiaClockModule import org.oppia.android.util.accessibility.AccessibilityTestModule import org.oppia.android.util.caching.AssetModule import org.oppia.android.util.caching.testing.CachingTestModule +import org.oppia.android.util.extensions.getProto import org.oppia.android.util.gcsresource.GcsResourceModule import org.oppia.android.util.locale.LocaleProdModule import org.oppia.android.util.logging.LoggerModule @@ -113,6 +118,7 @@ import org.oppia.android.util.parser.html.HtmlParserEntityTypeModule import org.oppia.android.util.parser.image.ImageParsingModule import org.oppia.android.util.platformparameter.EnableExtraTopicTabsUi import org.oppia.android.util.platformparameter.PlatformParameterValue +import org.oppia.android.util.profile.CurrentUserProfileIdIntentDecorator.extractCurrentUserProfileId import org.robolectric.annotation.Config import org.robolectric.annotation.LooperMode import javax.inject.Inject @@ -285,6 +291,37 @@ class TopicRevisionFragmentTest { } } + @Test + fun testFragment_argumentsAreCorrect() { + launchTopicActivityIntent( + profileId = profileId, + classroomId = TEST_CLASSROOM_ID_1, + topicId = FRACTIONS_TOPIC_ID + ).use { scenario -> + clickRevisionTab() + testCoroutineDispatchers.runCurrent() + scenario.onActivity { activity -> + + val topicFragment = activity.supportFragmentManager + .findFragmentById(R.id.topic_fragment_placeholder) as TopicFragment + val viewPager = topicFragment.requireView() + .findViewById(R.id.topic_tabs_viewpager) + val topicRevisionFragment = topicFragment.childFragmentManager + .findFragmentByTag("f${viewPager.currentItem}") as TopicRevisionFragment + + val receivedInternalProfileId = topicRevisionFragment + .arguments?.extractCurrentUserProfileId()?.internalId ?: -1 + val args = topicRevisionFragment.arguments?.getProto( + TopicRevisionFragment.TOPIC_REVISION_FRAGMENT_ARGUMENTS_KEY, + TopicRevisionFragmentArguments.getDefaultInstance() + ) + + assertThat(receivedInternalProfileId).isEqualTo(profileId.internalId) + assertThat(args?.topicId).isEqualTo(FRACTIONS_TOPIC_ID) + } + } + } + private fun markAllSpotlightsSeen() { spotlightStateController.markSpotlightViewed(profileId, TOPIC_LESSON_TAB) testCoroutineDispatchers.runCurrent() diff --git a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt index 608d84b0b19..cff6fdf44d9 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/walkthrough/WalkthroughFinalFragmentTest.kt @@ -18,6 +18,7 @@ import androidx.test.espresso.matcher.ViewMatchers.isRoot import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat import dagger.Component import org.hamcrest.CoreMatchers.containsString import org.junit.After @@ -37,12 +38,14 @@ import org.oppia.android.app.application.ApplicationStartupListenerModule import org.oppia.android.app.application.testing.TestingBuildFlavorModule import org.oppia.android.app.devoptions.DeveloperOptionsModule import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule +import org.oppia.android.app.model.WalkthroughFinalFragmentArguments import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPositionOnView import org.oppia.android.app.shim.ViewBindingShimModule import org.oppia.android.app.translation.testing.ActivityRecreatorTestModule import org.oppia.android.app.utility.OrientationChangeAction.Companion.orientationLandscape import org.oppia.android.app.utility.ProgressMatcher.Companion.withProgress +import org.oppia.android.app.walkthrough.end.WalkthroughFinalFragment import org.oppia.android.data.backends.gae.NetworkConfigProdModule import org.oppia.android.data.backends.gae.NetworkModule import org.oppia.android.domain.classify.InteractionsModule @@ -73,6 +76,7 @@ import org.oppia.android.domain.oppialogger.loguploader.LogReportWorkerModule import org.oppia.android.domain.platformparameter.PlatformParameterModule import org.oppia.android.domain.platformparameter.PlatformParameterSingletonModule import org.oppia.android.domain.question.QuestionModule +import org.oppia.android.domain.topic.FRACTIONS_TOPIC_ID import org.oppia.android.domain.workmanager.WorkManagerConfigurationModule import org.oppia.android.testing.OppiaTestRule import org.oppia.android.testing.TestLogReportingModule @@ -85,6 +89,7 @@ import org.oppia.android.testing.time.FakeOppiaClockModule import org.oppia.android.util.accessibility.AccessibilityTestModule import org.oppia.android.util.caching.AssetModule import org.oppia.android.util.caching.testing.CachingTestModule +import org.oppia.android.util.extensions.getProto import org.oppia.android.util.gcsresource.GcsResourceModule import org.oppia.android.util.locale.LocaleProdModule import org.oppia.android.util.logging.LoggerModule @@ -267,6 +272,33 @@ class WalkthroughFinalFragmentTest { } } + @Test + fun testFragment_argumentsAreCorrect() { + launch(createWalkthroughActivityIntent(0)).use { scenario -> + testCoroutineDispatchers.runCurrent() + scenario.onActivity { activity -> + activity.pageWithTopicId(WalkthroughPages.FINAL.value, FRACTIONS_TOPIC_ID) + + val walkthroughFinalFragment = activity.supportFragmentManager + .findFragmentById(R.id.walkthrough_fragment_placeholder) as WalkthroughFinalFragment + + val arguments = + checkNotNull(walkthroughFinalFragment.arguments) { + "Expected arguments to be passed to WalkthroughFinalFragment" + } + val args = arguments.getProto( + WalkthroughFinalFragment.WALKTHROUGH_FINAL_FRAGMENT_ARGUMENTS_KEY, + WalkthroughFinalFragmentArguments.getDefaultInstance() + ) + val receivedTopicId = checkNotNull(args.topicId) { + "Expected topicId to be passed to WalkthroughFinalFragment" + } + + assertThat(receivedTopicId).isEqualTo(FRACTIONS_TOPIC_ID) + } + } + } + private fun setUpTestApplicationComponent() { ApplicationProvider.getApplicationContext().inject(this) } diff --git a/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt b/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt index 54178d81774..08185ec5033 100644 --- a/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt +++ b/app/src/test/java/org/oppia/android/app/testing/options/OptionsFragmentTest.kt @@ -2,6 +2,7 @@ package org.oppia.android.app.testing.options import android.app.Application import android.content.Intent +import android.widget.FrameLayout import androidx.appcompat.app.AppCompatActivity import androidx.test.core.app.ActivityScenario.launch import androidx.test.core.app.ApplicationProvider @@ -27,10 +28,14 @@ import org.oppia.android.app.application.ApplicationStartupListenerModule import org.oppia.android.app.application.testing.TestingBuildFlavorModule import org.oppia.android.app.devoptions.DeveloperOptionsModule import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule +import org.oppia.android.app.model.OptionsFragmentArguments import org.oppia.android.app.model.ProfileId import org.oppia.android.app.options.AppLanguageFragment import org.oppia.android.app.options.AudioLanguageFragment +import org.oppia.android.app.options.OPTIONS_FRAGMENT_ARGUMENTS_KEY import org.oppia.android.app.options.OptionsActivity +import org.oppia.android.app.options.OptionsFragment +import org.oppia.android.app.options.READING_TEXT_SIZE_FRAGMENT import org.oppia.android.app.options.ReadingTextSizeFragment import org.oppia.android.app.player.state.itemviewmodel.SplitScreenInteractionModule import org.oppia.android.app.recyclerview.RecyclerViewMatcher.Companion.atPositionOnView @@ -78,6 +83,7 @@ import org.oppia.android.testing.time.FakeOppiaClockModule import org.oppia.android.util.accessibility.AccessibilityTestModule import org.oppia.android.util.caching.AssetModule import org.oppia.android.util.caching.testing.CachingTestModule +import org.oppia.android.util.extensions.getProto import org.oppia.android.util.gcsresource.GcsResourceModule import org.oppia.android.util.locale.LocaleProdModule import org.oppia.android.util.logging.LoggerModule @@ -197,6 +203,39 @@ class OptionsFragmentTest { } } + @Test + fun testFragment_argumentsAreCorrect() { + launch( + createOptionActivityIntent( + internalProfileId = 0, + isFromNavigationDrawer = true + ) + ).use { scenario -> + testCoroutineDispatchers.runCurrent() + scenario.onActivity { activity -> + + val optionsFragment = activity.supportFragmentManager + .findFragmentById(R.id.options_fragment_placeholder) as OptionsFragment + + val args = optionsFragment.arguments?.getProto( + OPTIONS_FRAGMENT_ARGUMENTS_KEY, + OptionsFragmentArguments.getDefaultInstance() + ) + + val isMultipane = + activity.findViewById(R.id.multipane_options_container) != null + + val receivedIsMultipane = args?.isMultipane + val receivedIsFirstOpen = args?.isFirstOpen + val receivedSelectedFragment = checkNotNull(args?.selectedFragment) + + assertThat(receivedIsMultipane).isEqualTo(isMultipane) + assertThat(receivedIsFirstOpen).isEqualTo(true) + assertThat(receivedSelectedFragment).isEqualTo(READING_TEXT_SIZE_FRAGMENT) + } + } + } + private fun createOptionActivityIntent( internalProfileId: Int, isFromNavigationDrawer: Boolean