Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -5830,14 +5830,61 @@ class StateFragmentTest {
}
}

@Test
fun testFlashback_featureFlagOff_thenFeatureFlagOn() {
// Set up the previous app instance with the flashback feature flag OFF.
TestPlatformParameterModule.forceEnableFlashbackSupport(false)
executeInPreviousAppInstance { _ -> }

// In the current app instance, enable the feature flag and verify flashback button is shown.
setUpTestWithFlashbackFeatureOn()
launchForExploration(TEST_EXPLORATION_ID_2, shouldSavePartialProgress = false).use {
startPlayingExploration()

navigateToPrototypeRatioInputState()

// Submit wrong answer.
typeRatioExpression("4:8")
clickSubmitAnswerButton()

// Verify flashback button is visible.
scrollToViewType(FLASHBACK_BUTTON)
onView(withId(R.id.flashback_button)).check(
matches(withText(R.string.state_flashback_button))
)
}
}

@Test
fun testFlashback_featureFlagOn_persistsAcrossAppInstances() {
// Set up the previous app instance with the flashback feature flag ON.
TestPlatformParameterModule.forceEnableFlashbackSupport(true)
executeInPreviousAppInstance { _ -> }

// In the current app instance, flag should still be on.
setUpTestWithFlashbackFeatureOn()
launchForExploration(TEST_EXPLORATION_ID_2, shouldSavePartialProgress = false).use {
startPlayingExploration()

navigateToPrototypeRatioInputState()

// Submit wrong answer.
typeRatioExpression("4:8")
clickSubmitAnswerButton()

// Verify flashback button IS shown (flag persisted across app instances).
scrollToViewType(FLASHBACK_BUTTON)
onView(withId(R.id.flashback_button)).check(matches(isDisplayed()))
}
}

@Test
fun testStateFragment_submitMultipleChoiceAnswer_verifyMultipleChoiceSubmittedAnswer() {
setUpTestWithFlashbackFeatureOn()
launchForExploration(TEST_EXPLORATION_ID_2, shouldSavePartialProgress = false).use {
startPlayingExploration()
playThroughPrototypeState1()
playThroughPrototypeState2()

// Submit Multiple choice answer.
selectMultipleChoiceOption(optionPosition = 2, expectedOptionText = "Eagle")
clickSubmitAnswerButton()
Expand Down Expand Up @@ -7075,6 +7122,31 @@ class StateFragmentTest {
fun isOnRobolectric(): Boolean
}

/**
* Creates a separate test application component and executes the specified block. This should be
* called before setUpTestApplicationComponent to avoid undefined behavior in production code.
* This can be used to simulate arranging state in a "prior" run of the app.
*
* Note that only dependencies fetched from the specified [TestApplicationComponent] should be
* used, not any class-level injected dependencies.
*/
private fun executeInPreviousAppInstance(block: (TestApplicationComponent) -> Unit) {
val testApplication = TestApplication()
// The true application is hooked as a base context. This is to make sure the new application
// can behave like a real Android application class (per Robolectric) without having a shared
// Dagger dependency graph with the application under test.
testApplication.attachBaseContext(ApplicationProvider.getApplicationContext())
block(
DaggerStateFragmentTest_TestApplicationComponent.builder()
.setApplication(testApplication)
.build()
)

// Resetting after the previous instance is important so that the next (main) app instance
// can set its own flags.
TestPlatformParameterModule.reset()
}

class TestApplication : Application(), ActivityComponentFactory, ApplicationInjectorProvider {
private val component: TestApplicationComponent by lazy {
DaggerStateFragmentTest_TestApplicationComponent.builder()
Expand All @@ -7090,6 +7162,10 @@ class StateFragmentTest {
return component.getActivityComponentBuilderProvider().get().setActivity(activity).build()
}

public override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
}

override fun getApplicationInjector(): ApplicationInjector = component
}

Expand Down
Loading