diff --git a/BUILD.bazel b/BUILD.bazel index 90b90741cb4..7c32ed280d1 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -36,6 +36,13 @@ package_group( ], ) +package_group( + name = "oppia_e2e_testing_visibility", + packages = [ + "//instrumentation/...", + ], +) + # Special visibility group specific to debug mode. This provides access to the target for both the # Oppia tests and specific debug only packages. package_group( diff --git a/app/BUILD.bazel b/app/BUILD.bazel index df738dc9f82..37e38f5e126 100644 --- a/app/BUILD.bazel +++ b/app/BUILD.bazel @@ -665,6 +665,7 @@ kt_android_library( ":resources", ":view_models", ":views", + "//data/src/main/java/org/oppia/android/data/backends/gae:network_config_prod_module", "//data/src/main/java/org/oppia/android/data/backends/gae:prod_module", "//model:arguments_java_proto_lite", "//third_party:androidx_databinding_databinding-adapters", diff --git a/app/src/main/java/org/oppia/android/app/application/ApplicationComponent.kt b/app/src/main/java/org/oppia/android/app/application/ApplicationComponent.kt index 79f403ec3dc..401b3062f4d 100644 --- a/app/src/main/java/org/oppia/android/app/application/ApplicationComponent.kt +++ b/app/src/main/java/org/oppia/android/app/application/ApplicationComponent.kt @@ -10,6 +10,7 @@ import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule import org.oppia.android.app.shim.IntentFactoryShimModule import org.oppia.android.app.shim.ViewBindingShimModule import org.oppia.android.app.topic.PracticeTabModule +import org.oppia.android.data.backends.gae.NetworkConfigProdModule import org.oppia.android.data.backends.gae.NetworkModule import org.oppia.android.domain.classify.InteractionsModule import org.oppia.android.domain.classify.rules.continueinteraction.ContinueModule @@ -81,7 +82,7 @@ import javax.inject.Singleton FirebaseLogUploaderModule::class, NetworkModule::class, PracticeTabModule::class, PlatformParameterModule::class, ExplorationStorageModule::class, DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class, - NetworkConnectionUtilDebugModule::class, + NetworkConnectionUtilDebugModule::class, NetworkConfigProdModule::class, // TODO(#59): Remove this module once we completely migrate to Bazel from Gradle as we can then // directly exclude debug files from the build and thus won't be requiring this module. NetworkConnectionDebugUtilModule::class diff --git a/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt b/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt index f732abf2dcd..d0613302c59 100644 --- a/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt +++ b/app/src/sharedTest/java/org/oppia/android/app/help/HelpActivityTest.kt @@ -25,6 +25,7 @@ import org.oppia.android.app.devoptions.DeveloperOptionsModule import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule import org.oppia.android.app.shim.ViewBindingShimModule import org.oppia.android.app.topic.PracticeTabModule +import org.oppia.android.data.backends.gae.NetworkConfigProdModule import org.oppia.android.data.backends.gae.NetworkModule import org.oppia.android.domain.classify.InteractionsModule import org.oppia.android.domain.classify.rules.continueinteraction.ContinueModule @@ -131,8 +132,8 @@ class HelpActivityTest { HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class, FirebaseLogUploaderModule::class, FakeOppiaClockModule::class, PracticeTabModule::class, DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class, - ExplorationStorageModule::class, NetworkConnectionUtilDebugModule::class, - NetworkConnectionDebugUtilModule::class + ExplorationStorageModule::class, NetworkConfigProdModule::class, + NetworkConnectionUtilDebugModule::class, NetworkConnectionDebugUtilModule::class ] ) interface TestApplicationComponent : ApplicationComponent { diff --git a/data/BUILD.bazel b/data/BUILD.bazel index 3205f515f92..3dc0dde487c 100644 --- a/data/BUILD.bazel +++ b/data/BUILD.bazel @@ -9,6 +9,7 @@ load("//data:data_test.bzl", "data_test") # keep sorted TEST_DEPS = [ ":dagger", + "//data/src/main/java/org/oppia/android/data/backends/gae:network_config_prod_module", "//data/src/main/java/org/oppia/android/data/backends/gae:oppia_retrofit", "//data/src/main/java/org/oppia/android/data/backends/gae:prod_module", "//data/src/main/java/org/oppia/android/data/backends/gae/model", diff --git a/data/src/main/java/org/oppia/android/data/backends/gae/BUILD.bazel b/data/src/main/java/org/oppia/android/data/backends/gae/BUILD.bazel index d0c4c3a73fe..33776d70013 100644 --- a/data/src/main/java/org/oppia/android/data/backends/gae/BUILD.bazel +++ b/data/src/main/java/org/oppia/android/data/backends/gae/BUILD.bazel @@ -16,7 +16,7 @@ kt_android_library( visibility = ["//:oppia_testing_visibility"], deps = [ ":constants", - ":network_settings", + ":network_config_annotations", "//model:arguments_java_proto_lite", "//third_party:com_squareup_okhttp3_okhttp", "//third_party:javax_inject_javax_inject", @@ -25,11 +25,15 @@ kt_android_library( ) kt_android_library( - name = "network_settings", + name = "network_config_prod_module", srcs = [ - "NetworkSettings.kt", + "NetworkConfigProdModule.kt", + ], + visibility = ["//:oppia_prod_module_visibility"], + deps = [ + ":dagger", + ":network_config_annotations", ], - visibility = ["//:oppia_testing_visibility"], ) kt_android_library( @@ -39,14 +43,26 @@ kt_android_library( ], ) +kt_android_library( + name = "network_config_annotations", + srcs = [ + "BaseUrl.kt", + "XssiPrefix.kt", + ], + visibility = ["//:oppia_api_visibility"], + deps = [ + "//third_party:javax_inject_javax_inject", + ], +) + kt_android_library( name = "oppia_retrofit", srcs = [ "OppiaRetrofit.kt", ], - visibility = ["//:oppia_testing_visibility"], + visibility = ["//:oppia_api_visibility"], deps = [ - ":dagger", + "//third_party:javax_inject_javax_inject", ], ) @@ -58,8 +74,8 @@ kt_android_library( visibility = ["//:oppia_prod_module_visibility"], deps = [ ":dagger", + ":network_config_annotations", ":network_interceptors", - ":network_settings", ":oppia_retrofit", "//data/src/main/java/org/oppia/android/data/backends/gae/api", "//third_party:com_squareup_retrofit2_converter-moshi", diff --git a/data/src/main/java/org/oppia/android/data/backends/gae/BaseUrl.kt b/data/src/main/java/org/oppia/android/data/backends/gae/BaseUrl.kt new file mode 100644 index 00000000000..4202f62ac37 --- /dev/null +++ b/data/src/main/java/org/oppia/android/data/backends/gae/BaseUrl.kt @@ -0,0 +1,7 @@ +package org.oppia.android.data.backends.gae + +import javax.inject.Qualifier + +/** Qualifier for an application-injectable string representing the server URL used for networking. */ +@Qualifier +annotation class BaseUrl diff --git a/data/src/main/java/org/oppia/android/data/backends/gae/JsonPrefixNetworkInterceptor.kt b/data/src/main/java/org/oppia/android/data/backends/gae/JsonPrefixNetworkInterceptor.kt index 2a1b315071f..1a2c68b24f6 100755 --- a/data/src/main/java/org/oppia/android/data/backends/gae/JsonPrefixNetworkInterceptor.kt +++ b/data/src/main/java/org/oppia/android/data/backends/gae/JsonPrefixNetworkInterceptor.kt @@ -13,7 +13,9 @@ import javax.inject.Singleton * The Interceptor removes XSSI_PREFIX from every response to produce valid Json. */ @Singleton -class JsonPrefixNetworkInterceptor @Inject constructor() : Interceptor { +class JsonPrefixNetworkInterceptor @Inject constructor( + @XssiPrefix private val xssiPrefix: String +) : Interceptor { @Throws(IOException::class) override fun intercept(chain: Interceptor.Chain): Response { @@ -34,6 +36,6 @@ class JsonPrefixNetworkInterceptor @Inject constructor() : Interceptor { /** Removes the XSSI prefix from the specified raw JSON & returns the result. */ fun removeXssiPrefix(rawJson: String): String { - return rawJson.removePrefix(NetworkSettings.XSSI_PREFIX).trimStart() + return rawJson.removePrefix(xssiPrefix).trimStart() } } diff --git a/data/src/main/java/org/oppia/android/data/backends/gae/NetworkConfigProdModule.kt b/data/src/main/java/org/oppia/android/data/backends/gae/NetworkConfigProdModule.kt new file mode 100644 index 00000000000..0a6df7c531f --- /dev/null +++ b/data/src/main/java/org/oppia/android/data/backends/gae/NetworkConfigProdModule.kt @@ -0,0 +1,27 @@ +package org.oppia.android.data.backends.gae + +import dagger.Module +import dagger.Provides + +/** Provides network-specific constants. */ +@Module +class NetworkConfigProdModule { + + /** Provides BaseUrl that connects to production server. */ + @Provides + @BaseUrl + fun provideNetworkBaseUrl(): String { + return "https://oppia.org" + } + + /** + * Prefix in Json response for extra layer of security in API calls + * https://github.com/oppia/oppia/blob/8f9eed/feconf.py#L319 + * Remove this prefix from every Json response which is achieved in [NetworkInterceptor] + */ + @Provides + @XssiPrefix + fun provideXssiPrefix(): String { + return ")]}'" + } +} diff --git a/data/src/main/java/org/oppia/android/data/backends/gae/NetworkModule.kt b/data/src/main/java/org/oppia/android/data/backends/gae/NetworkModule.kt index 43bec6fb89b..7584f5059ef 100644 --- a/data/src/main/java/org/oppia/android/data/backends/gae/NetworkModule.kt +++ b/data/src/main/java/org/oppia/android/data/backends/gae/NetworkModule.kt @@ -28,7 +28,8 @@ class NetworkModule { @Singleton fun provideRetrofitInstance( jsonPrefixNetworkInterceptor: JsonPrefixNetworkInterceptor, - remoteAuthNetworkInterceptor: RemoteAuthNetworkInterceptor + remoteAuthNetworkInterceptor: RemoteAuthNetworkInterceptor, + @BaseUrl baseUrl: String ): Retrofit { val client = OkHttpClient.Builder() .addInterceptor(jsonPrefixNetworkInterceptor) @@ -36,7 +37,7 @@ class NetworkModule { .build() return Retrofit.Builder() - .baseUrl(NetworkSettings.getBaseUrl()) + .baseUrl(baseUrl) .addConverterFactory(MoshiConverterFactory.create()) .client(client) .build() diff --git a/data/src/main/java/org/oppia/android/data/backends/gae/NetworkSettings.kt b/data/src/main/java/org/oppia/android/data/backends/gae/NetworkSettings.kt deleted file mode 100755 index 8ad661ad237..00000000000 --- a/data/src/main/java/org/oppia/android/data/backends/gae/NetworkSettings.kt +++ /dev/null @@ -1,27 +0,0 @@ -package org.oppia.android.data.backends.gae - -/** An object that contains functions and constants specifically related to network only. */ -object NetworkSettings { - - private var isDeveloperMode: Boolean = true - - /** DEVELOPER URL which connects to development server */ - // TODO(#3623): Move this to DI graph - private const val DEVELOPER_URL = "https://oppia.org" - /** PRODUCTION URL which connects to production server */ - private const val PROD_URL = "https://oppia.org" - /** - * Prefix in Json response for extra layer of security in API calls - * https://github.com/oppia/oppia/blob/8f9eed/feconf.py#L319 - * Remove this prefix from every Json response which is achieved in [NetworkInterceptor] - */ - const val XSSI_PREFIX = ")]}\'" - - fun getBaseUrl(): String { - return if (isDeveloperMode) { - DEVELOPER_URL - } else { - PROD_URL - } - } -} diff --git a/data/src/main/java/org/oppia/android/data/backends/gae/XssiPrefix.kt b/data/src/main/java/org/oppia/android/data/backends/gae/XssiPrefix.kt new file mode 100644 index 00000000000..11be05caab8 --- /dev/null +++ b/data/src/main/java/org/oppia/android/data/backends/gae/XssiPrefix.kt @@ -0,0 +1,10 @@ +package org.oppia.android.data.backends.gae + +import javax.inject.Qualifier + +/** + * Qualifier for an application-injectable string representing the prefix in Json response used for + * security in API calls. + */ +@Qualifier +annotation class XssiPrefix diff --git a/data/src/test/java/org/oppia/android/data/backends/gae/JsonPrefixNetworkInterceptorTest.kt b/data/src/test/java/org/oppia/android/data/backends/gae/JsonPrefixNetworkInterceptorTest.kt index c59383a4d5d..dead9763549 100755 --- a/data/src/test/java/org/oppia/android/data/backends/gae/JsonPrefixNetworkInterceptorTest.kt +++ b/data/src/test/java/org/oppia/android/data/backends/gae/JsonPrefixNetworkInterceptorTest.kt @@ -19,7 +19,7 @@ import retrofit2.Retrofit import javax.inject.Inject import javax.inject.Singleton -/** Tests for [JsonPrefixNetworkInterceptorTest] */ +/** Tests for [JsonPrefixNetworkInterceptor]. */ @RunWith(AndroidJUnit4::class) @LooperMode(LooperMode.Mode.PAUSED) class JsonPrefixNetworkInterceptorTest { @@ -95,7 +95,7 @@ class JsonPrefixNetworkInterceptorTest { // TODO(#89): Move this to a common test application component. @Singleton - @Component(modules = [NetworkModule::class]) + @Component(modules = [TestNetworkModule::class, NetworkConfigProdModule::class]) interface TestApplicationComponent { @Component.Builder interface Builder { diff --git a/data/src/test/java/org/oppia/android/data/backends/gae/NetworkConfigProdModuleTest.kt b/data/src/test/java/org/oppia/android/data/backends/gae/NetworkConfigProdModuleTest.kt new file mode 100644 index 00000000000..023a5a3713e --- /dev/null +++ b/data/src/test/java/org/oppia/android/data/backends/gae/NetworkConfigProdModuleTest.kt @@ -0,0 +1,90 @@ +package org.oppia.android.data.backends.gae + +import android.app.Application +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import dagger.BindsInstance +import dagger.Component +import dagger.Module +import dagger.Provides +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config +import org.robolectric.annotation.LooperMode +import javax.inject.Inject +import javax.inject.Singleton + +/** Tests for [NetworkConfigProdModule]. */ +@RunWith(AndroidJUnit4::class) +@LooperMode(LooperMode.Mode.PAUSED) +@Config(application = NetworkConfigProdModuleTest.TestApplication::class) +class NetworkConfigProdModuleTest { + + @field:[Inject BaseUrl] + lateinit var baseUrl: String + + @field:[Inject XssiPrefix] + lateinit var xssiPrefix: String + + @Before + fun setUp() { + setUpTestApplicationComponent() + } + + @Test + fun testModule_baseUrl_isProdUrl() { + assertThat(baseUrl).isEqualTo("https://oppia.org") + } + + @Test + fun testModule_xssiPrefix_isXssiPrefix() { + assertThat(xssiPrefix).isEqualTo(")]}'") + } + + private fun setUpTestApplicationComponent() { + ApplicationProvider.getApplicationContext() + .inject(this) + } + + @Module + class TestModule { + @Provides + @Singleton + fun provideContext(application: Application): Context { + return application + } + } + + @Singleton + @Component( + modules = [ + TestModule::class, NetworkConfigProdModule::class + ] + ) + + interface TestApplicationComponent { + @Component.Builder + interface Builder { + @BindsInstance + fun setApplication(application: Application): Builder + fun build(): TestApplicationComponent + } + + fun inject(networkConfigModuleTest: NetworkConfigProdModuleTest) + } + + class TestApplication : Application() { + private val component: TestApplicationComponent by lazy { + DaggerNetworkConfigProdModuleTest_TestApplicationComponent.builder() + .setApplication(this) + .build() + } + + fun inject(networkConfigModuleTest: NetworkConfigProdModuleTest) { + component.inject(networkConfigModuleTest) + } + } +} diff --git a/data/src/test/java/org/oppia/android/data/backends/gae/RemoteAuthNetworkInterceptorTest.kt b/data/src/test/java/org/oppia/android/data/backends/gae/RemoteAuthNetworkInterceptorTest.kt index 3b21267f022..2c1cb4b62d8 100644 --- a/data/src/test/java/org/oppia/android/data/backends/gae/RemoteAuthNetworkInterceptorTest.kt +++ b/data/src/test/java/org/oppia/android/data/backends/gae/RemoteAuthNetworkInterceptorTest.kt @@ -36,7 +36,7 @@ import retrofit2.converter.moshi.MoshiConverterFactory import javax.inject.Inject import javax.inject.Singleton -/** Tests for [RemoteAuthNetworkInterceptor] */ +/** Tests for [RemoteAuthNetworkInterceptor]. */ @RunWith(AndroidJUnit4::class) @Config(application = RemoteAuthNetworkInterceptorTest.TestApplication::class) @LooperMode(LooperMode.Mode.PAUSED) diff --git a/data/src/test/java/org/oppia/android/data/backends/gae/api/ClassroomServiceTest.kt b/data/src/test/java/org/oppia/android/data/backends/gae/api/ClassroomServiceTest.kt index e51c4136b04..d087c2763ce 100755 --- a/data/src/test/java/org/oppia/android/data/backends/gae/api/ClassroomServiceTest.kt +++ b/data/src/test/java/org/oppia/android/data/backends/gae/api/ClassroomServiceTest.kt @@ -12,7 +12,9 @@ import dagger.Provides import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.oppia.android.data.backends.gae.NetworkConfigProdModule import org.oppia.android.data.backends.gae.NetworkModule +import org.oppia.android.data.backends.gae.XssiPrefix import org.oppia.android.testing.network.MockClassroomService import org.oppia.android.testing.network.RetrofitTestModule import org.robolectric.annotation.LooperMode @@ -30,6 +32,9 @@ class ClassroomServiceTest { @Inject lateinit var mockRetrofit: MockRetrofit + @field:[Inject XssiPrefix] + lateinit var xssiPrefix: String + @Before fun setUp() { setUpTestApplicationComponent() @@ -38,7 +43,7 @@ class ClassroomServiceTest { @Test fun testClassroomService_usingFakeJson_deserializationSuccessful() { val delegate = mockRetrofit.create(ClassroomService::class.java) - val mockClassroomService = MockClassroomService(delegate) + val mockClassroomService = MockClassroomService(delegate, xssiPrefix) val classroom = mockClassroomService.getClassroom("Math") val classroomResponse = classroom.execute() @@ -65,7 +70,12 @@ class ClassroomServiceTest { // TODO(#89): Move this to a common test application component. @Singleton - @Component(modules = [TestModule::class, NetworkModule::class, RetrofitTestModule::class]) + @Component( + modules = [ + TestModule::class, NetworkModule::class, + RetrofitTestModule::class, NetworkConfigProdModule::class + ] + ) interface TestApplicationComponent { @Component.Builder interface Builder { diff --git a/data/src/test/java/org/oppia/android/data/backends/gae/api/ConceptCardServiceTest.kt b/data/src/test/java/org/oppia/android/data/backends/gae/api/ConceptCardServiceTest.kt index f0ab85bc754..d2cae31541e 100755 --- a/data/src/test/java/org/oppia/android/data/backends/gae/api/ConceptCardServiceTest.kt +++ b/data/src/test/java/org/oppia/android/data/backends/gae/api/ConceptCardServiceTest.kt @@ -12,7 +12,9 @@ import dagger.Provides import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.oppia.android.data.backends.gae.NetworkConfigProdModule import org.oppia.android.data.backends.gae.NetworkModule +import org.oppia.android.data.backends.gae.XssiPrefix import org.oppia.android.testing.network.MockConceptCardService import org.oppia.android.testing.network.RetrofitTestModule import org.robolectric.annotation.LooperMode @@ -30,6 +32,9 @@ class ConceptCardServiceTest { @Inject lateinit var mockRetrofit: MockRetrofit + @field:[Inject XssiPrefix] + lateinit var xssiPrefix: String + @Before fun setUp() { setUpTestApplicationComponent() @@ -38,7 +43,7 @@ class ConceptCardServiceTest { @Test fun testConceptCardService_usingFakeJson_deserializationSuccessful() { val delegate = mockRetrofit.create(ConceptCardService::class.java) - val mockConceptCardService = MockConceptCardService(delegate) + val mockConceptCardService = MockConceptCardService(delegate, xssiPrefix) val skillIdList = ArrayList() skillIdList.add("1") @@ -71,7 +76,12 @@ class ConceptCardServiceTest { // TODO(#89): Move this to a common test application component. @Singleton - @Component(modules = [TestModule::class, NetworkModule::class, RetrofitTestModule::class]) + @Component( + modules = [ + TestModule::class, NetworkModule::class, + RetrofitTestModule::class, NetworkConfigProdModule::class + ] + ) interface TestApplicationComponent { @Component.Builder interface Builder { diff --git a/data/src/test/java/org/oppia/android/data/backends/gae/api/ExplorationServiceTest.kt b/data/src/test/java/org/oppia/android/data/backends/gae/api/ExplorationServiceTest.kt index 4c4c572601d..7f0fcf3b6ad 100755 --- a/data/src/test/java/org/oppia/android/data/backends/gae/api/ExplorationServiceTest.kt +++ b/data/src/test/java/org/oppia/android/data/backends/gae/api/ExplorationServiceTest.kt @@ -12,7 +12,9 @@ import dagger.Provides import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.oppia.android.data.backends.gae.NetworkConfigProdModule import org.oppia.android.data.backends.gae.NetworkModule +import org.oppia.android.data.backends.gae.XssiPrefix import org.oppia.android.testing.network.MockExplorationService import org.oppia.android.testing.network.RetrofitTestModule import org.robolectric.annotation.LooperMode @@ -30,6 +32,9 @@ class ExplorationServiceTest { @Inject lateinit var mockRetrofit: MockRetrofit + @field:[Inject XssiPrefix] + lateinit var xssiPrefix: String + @Before fun setUp() { setUpTestApplicationComponent() @@ -38,7 +43,7 @@ class ExplorationServiceTest { @Test fun testExplorationService_usingFakeJson_deserializationSuccessful() { val delegate = mockRetrofit.create(ExplorationService::class.java) - val mockExplorationService = MockExplorationService(delegate) + val mockExplorationService = MockExplorationService(delegate, xssiPrefix) val explorationContainer = mockExplorationService.getExplorationById("4") val explorationContainerResponse = explorationContainer.execute() @@ -65,7 +70,12 @@ class ExplorationServiceTest { // TODO(#89): Move this to a common test application component. @Singleton - @Component(modules = [TestModule::class, NetworkModule::class, RetrofitTestModule::class]) + @Component( + modules = [ + TestModule::class, NetworkModule::class, + RetrofitTestModule::class, NetworkConfigProdModule::class + ] + ) interface TestApplicationComponent { @Component.Builder interface Builder { diff --git a/data/src/test/java/org/oppia/android/data/backends/gae/api/FeedbackReportingServiceTest.kt b/data/src/test/java/org/oppia/android/data/backends/gae/api/FeedbackReportingServiceTest.kt index 09286150cf1..9706233c306 100644 --- a/data/src/test/java/org/oppia/android/data/backends/gae/api/FeedbackReportingServiceTest.kt +++ b/data/src/test/java/org/oppia/android/data/backends/gae/api/FeedbackReportingServiceTest.kt @@ -14,6 +14,7 @@ import dagger.Provides import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.oppia.android.data.backends.gae.NetworkConfigProdModule import org.oppia.android.data.backends.gae.NetworkModule import org.oppia.android.data.backends.gae.model.GaeFeedbackReport import org.oppia.android.testing.network.ApiMockLoader @@ -76,7 +77,12 @@ class FeedbackReportingServiceTest { // TODO(#89): Move this to a common test application component. @Singleton - @Component(modules = [TestModule::class, NetworkModule::class, RetrofitTestModule::class]) + @Component( + modules = [ + TestModule::class, NetworkModule::class, + RetrofitTestModule::class, NetworkConfigProdModule::class + ] + ) interface TestApplicationComponent { @Component.Builder interface Builder { diff --git a/data/src/test/java/org/oppia/android/data/backends/gae/api/PlatformParameterServiceTest.kt b/data/src/test/java/org/oppia/android/data/backends/gae/api/PlatformParameterServiceTest.kt index 3af047f943a..1c700e14eec 100644 --- a/data/src/test/java/org/oppia/android/data/backends/gae/api/PlatformParameterServiceTest.kt +++ b/data/src/test/java/org/oppia/android/data/backends/gae/api/PlatformParameterServiceTest.kt @@ -15,6 +15,7 @@ import okhttp3.mockwebserver.MockWebServer import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.oppia.android.data.backends.gae.NetworkConfigProdModule import org.oppia.android.data.backends.gae.NetworkModule import org.oppia.android.testing.network.MockPlatformParameterService import org.oppia.android.testing.network.RetrofitTestModule @@ -153,7 +154,8 @@ class PlatformParameterServiceTest { @Singleton @Component( modules = [ - TestModule::class, NetworkModule::class, RetrofitTestModule::class + TestModule::class, NetworkModule::class, + RetrofitTestModule::class, NetworkConfigProdModule::class ] ) interface TestApplicationComponent { diff --git a/data/src/test/java/org/oppia/android/data/backends/gae/api/QuestionPlayerServiceTest.kt b/data/src/test/java/org/oppia/android/data/backends/gae/api/QuestionPlayerServiceTest.kt index 0d9c8be2cbf..14afd34c90f 100755 --- a/data/src/test/java/org/oppia/android/data/backends/gae/api/QuestionPlayerServiceTest.kt +++ b/data/src/test/java/org/oppia/android/data/backends/gae/api/QuestionPlayerServiceTest.kt @@ -12,7 +12,9 @@ import dagger.Provides import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.oppia.android.data.backends.gae.NetworkConfigProdModule import org.oppia.android.data.backends.gae.NetworkModule +import org.oppia.android.data.backends.gae.XssiPrefix import org.oppia.android.testing.network.MockQuestionPlayerService import org.oppia.android.testing.network.RetrofitTestModule import org.robolectric.annotation.LooperMode @@ -30,6 +32,9 @@ class QuestionPlayerServiceTest { @Inject lateinit var mockRetrofit: MockRetrofit + @field:[Inject XssiPrefix] + lateinit var xssiPrefix: String + @Before fun setUp() { setUpTestApplicationComponent() @@ -38,7 +43,7 @@ class QuestionPlayerServiceTest { @Test fun testQuestionPlayerService_usingFakeJson_deserializationSuccessful() { val delegate = mockRetrofit.create(QuestionPlayerService::class.java) - val mockQuestionPlayerService = MockQuestionPlayerService(delegate) + val mockQuestionPlayerService = MockQuestionPlayerService(delegate, xssiPrefix) val skillIdList = ArrayList() skillIdList.add("1") @@ -70,7 +75,12 @@ class QuestionPlayerServiceTest { // TODO(#89): Move this to a common test application component. @Singleton - @Component(modules = [TestModule::class, NetworkModule::class, RetrofitTestModule::class]) + @Component( + modules = [ + TestModule::class, NetworkModule::class, + RetrofitTestModule::class, NetworkConfigProdModule::class + ] + ) interface TestApplicationComponent { @Component.Builder interface Builder { diff --git a/data/src/test/java/org/oppia/android/data/backends/gae/api/StoryServiceTest.kt b/data/src/test/java/org/oppia/android/data/backends/gae/api/StoryServiceTest.kt index 157f2844564..0080b1793d9 100755 --- a/data/src/test/java/org/oppia/android/data/backends/gae/api/StoryServiceTest.kt +++ b/data/src/test/java/org/oppia/android/data/backends/gae/api/StoryServiceTest.kt @@ -12,7 +12,9 @@ import dagger.Provides import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.oppia.android.data.backends.gae.NetworkConfigProdModule import org.oppia.android.data.backends.gae.NetworkModule +import org.oppia.android.data.backends.gae.XssiPrefix import org.oppia.android.testing.network.MockStoryService import org.oppia.android.testing.network.RetrofitTestModule import org.robolectric.annotation.LooperMode @@ -30,6 +32,9 @@ class StoryServiceTest { @Inject lateinit var mockRetrofit: MockRetrofit + @field:[Inject XssiPrefix] + lateinit var xssiPrefix: String + @Before fun setUp() { setUpTestApplicationComponent() @@ -38,7 +43,7 @@ class StoryServiceTest { @Test fun testStoryService_usingFakeJson_deserializationSuccessful() { val delegate = mockRetrofit.create(StoryService::class.java) - val mockStoryService = MockStoryService(delegate) + val mockStoryService = MockStoryService(delegate, xssiPrefix) val story = mockStoryService.getStory("1", "randomUserId", "rt4914") val storyResponse = story.execute() @@ -65,7 +70,12 @@ class StoryServiceTest { // TODO(#89): Move this to a common test application component. @Singleton - @Component(modules = [TestModule::class, NetworkModule::class, RetrofitTestModule::class]) + @Component( + modules = [ + TestModule::class, NetworkModule::class, + RetrofitTestModule::class, NetworkConfigProdModule::class + ] + ) interface TestApplicationComponent { @Component.Builder interface Builder { diff --git a/data/src/test/java/org/oppia/android/data/backends/gae/api/SubtopicServiceTest.kt b/data/src/test/java/org/oppia/android/data/backends/gae/api/SubtopicServiceTest.kt index b6bcde80e3c..3cdd9b8c7ff 100755 --- a/data/src/test/java/org/oppia/android/data/backends/gae/api/SubtopicServiceTest.kt +++ b/data/src/test/java/org/oppia/android/data/backends/gae/api/SubtopicServiceTest.kt @@ -12,7 +12,9 @@ import dagger.Provides import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.oppia.android.data.backends.gae.NetworkConfigProdModule import org.oppia.android.data.backends.gae.NetworkModule +import org.oppia.android.data.backends.gae.XssiPrefix import org.oppia.android.testing.network.MockSubtopicService import org.oppia.android.testing.network.RetrofitTestModule import org.robolectric.annotation.LooperMode @@ -30,6 +32,9 @@ class SubtopicServiceTest { @Inject lateinit var mockRetrofit: MockRetrofit + @field:[Inject XssiPrefix] + lateinit var xssiPrefix: String + @Before fun setUp() { setUpTestApplicationComponent() @@ -38,7 +43,7 @@ class SubtopicServiceTest { @Test fun testSubtopicService_usingFakeJson_deserializationSuccessful() { val delegate = mockRetrofit.create(SubtopicService::class.java) - val mockSubtopicService = MockSubtopicService(delegate) + val mockSubtopicService = MockSubtopicService(delegate, xssiPrefix) val subtopic = mockSubtopicService.getSubtopic("Subtopic 1", "randomId") val subtopicResponse = subtopic.execute() @@ -65,7 +70,12 @@ class SubtopicServiceTest { // TODO(#89): Move this to a common test application component. @Singleton - @Component(modules = [TestModule::class, NetworkModule::class, RetrofitTestModule::class]) + @Component( + modules = [ + TestModule::class, NetworkModule::class, + RetrofitTestModule::class, NetworkConfigProdModule::class + ] + ) interface TestApplicationComponent { @Component.Builder interface Builder { diff --git a/data/src/test/java/org/oppia/android/data/backends/gae/api/TopicServiceTest.kt b/data/src/test/java/org/oppia/android/data/backends/gae/api/TopicServiceTest.kt index e87ca943e44..decd66a6642 100755 --- a/data/src/test/java/org/oppia/android/data/backends/gae/api/TopicServiceTest.kt +++ b/data/src/test/java/org/oppia/android/data/backends/gae/api/TopicServiceTest.kt @@ -12,7 +12,9 @@ import dagger.Provides import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.oppia.android.data.backends.gae.NetworkConfigProdModule import org.oppia.android.data.backends.gae.NetworkModule +import org.oppia.android.data.backends.gae.XssiPrefix import org.oppia.android.testing.network.MockTopicService import org.oppia.android.testing.network.RetrofitTestModule import org.robolectric.annotation.LooperMode @@ -30,6 +32,9 @@ class TopicServiceTest { @Inject lateinit var mockRetrofit: MockRetrofit + @field:[Inject XssiPrefix] + lateinit var xssiPrefix: String + @Before fun setUp() { setUpTestApplicationComponent() @@ -38,7 +43,7 @@ class TopicServiceTest { @Test fun testTopicService_usingFakeJson_deserializationSuccessful() { val delegate = mockRetrofit.create(TopicService::class.java) - val mockTopicService = MockTopicService(delegate) + val mockTopicService = MockTopicService(delegate, xssiPrefix) val topic = mockTopicService.getTopicByName("Topic1") val topicResponse = topic.execute() @@ -65,7 +70,12 @@ class TopicServiceTest { // TODO(#89): Move this to a common test application component. @Singleton - @Component(modules = [TestModule::class, NetworkModule::class, RetrofitTestModule::class]) + @Component( + modules = [ + TestModule::class, NetworkModule::class, + RetrofitTestModule::class, NetworkConfigProdModule::class + ] + ) interface TestApplicationComponent { @Component.Builder interface Builder { diff --git a/instrumentation/BUILD.bazel b/instrumentation/BUILD.bazel index 6dc61c1ce98..2780c833061 100644 --- a/instrumentation/BUILD.bazel +++ b/instrumentation/BUILD.bazel @@ -14,7 +14,7 @@ android_binary( testonly = True, custom_package = "org.oppia.android", enable_data_binding = True, - manifest = "//app:src/main/AndroidManifest.xml", + manifest = "//instrumentation:src/java/AndroidManifest.xml", manifest_values = { "applicationId": "org.oppia.android", "minSdkVersion": "19", @@ -23,8 +23,9 @@ android_binary( "versionName": "0.1-test", }, multidex = "native", - visibility = ["//:oppia_testing_visibility"], + visibility = ["//:oppia_e2e_testing_visibility"], deps = [ "//app", + "//instrumentation/src/java/org/oppia/android/instrumentation/application:oppia_test_application", ], ) diff --git a/instrumentation/src/java/AndroidManifest.xml b/instrumentation/src/java/AndroidManifest.xml new file mode 100644 index 00000000000..b089ccec5ef --- /dev/null +++ b/instrumentation/src/java/AndroidManifest.xml @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/application/BUILD.bazel b/instrumentation/src/java/org/oppia/android/instrumentation/application/BUILD.bazel new file mode 100644 index 00000000000..b65fba2144f --- /dev/null +++ b/instrumentation/src/java/org/oppia/android/instrumentation/application/BUILD.bazel @@ -0,0 +1,29 @@ +""" +This library contains the test application and modules used to build the test app for end-to-end tests. +""" + +load("@dagger//:workspace_defs.bzl", "dagger_rules") +load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_android_library") + +kt_android_library( + name = "oppia_test_application", + testonly = True, + srcs = [ + "EndToEndTestGcsResourceModule.kt", + "EndToEndTestImageParsingModule.kt", + "EndToEndTestNetworkConfigModule.kt", + "OppiaTestApplication.kt", + "TestApplicationComponent.kt", + ], + visibility = ["//:oppia_e2e_testing_visibility"], + deps = [ + ":dagger", + "//app", + "//data/src/main/java/org/oppia/android/data/backends/gae:network_config_annotations", + "//domain", + "//utility", + "//utility/src/main/java/org/oppia/android/util/caching:caching_module", + ], +) + +dagger_rules() diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/application/EndToEndTestGcsResourceModule.kt b/instrumentation/src/java/org/oppia/android/instrumentation/application/EndToEndTestGcsResourceModule.kt new file mode 100644 index 00000000000..d32012329ea --- /dev/null +++ b/instrumentation/src/java/org/oppia/android/instrumentation/application/EndToEndTestGcsResourceModule.kt @@ -0,0 +1,22 @@ +package org.oppia.android.instrumentation.application + +import dagger.Module +import dagger.Provides +import org.oppia.android.util.gcsresource.DefaultResourceBucketName +import org.oppia.android.util.gcsresource.QuestionResourceBucketName + +/** Provides fake GCS resources for e2e tests (i.e. the local dev server). */ +@Module +class EndToEndTestGcsResourceModule { + @Provides + @DefaultResourceBucketName + fun provideDefaultGcsResource(): String { + return "assetsdevhandler" + } + + @Provides + @QuestionResourceBucketName + fun provideQuestionResourceBucketName(): String { + return "assetsdevhandler" + } +} diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/application/EndToEndTestImageParsingModule.kt b/instrumentation/src/java/org/oppia/android/instrumentation/application/EndToEndTestImageParsingModule.kt new file mode 100644 index 00000000000..3c2ff918ca4 --- /dev/null +++ b/instrumentation/src/java/org/oppia/android/instrumentation/application/EndToEndTestImageParsingModule.kt @@ -0,0 +1,33 @@ +package org.oppia.android.instrumentation.application + +import dagger.Module +import dagger.Provides +import org.oppia.android.util.parser.image.DefaultGcsPrefix +import org.oppia.android.util.parser.image.ImageDownloadUrlTemplate +import org.oppia.android.util.parser.image.ThumbnailDownloadUrlTemplate +import javax.inject.Singleton + +/** Provides image-extraction URL dependencies from local dev server. */ +@Module +class EndToEndTestImageParsingModule { + @Provides + @DefaultGcsPrefix + @Singleton + fun provideDefaultGcsPrefix(): String { + return "http://localhost:8181/" + } + + @Provides + @ImageDownloadUrlTemplate + @Singleton + fun provideImageDownloadUrlTemplate(): String { + return "%s/%s/assets/image/%s" + } + + @Provides + @ThumbnailDownloadUrlTemplate + @Singleton + fun provideThumbnailDownloadUrlTemplate(): String { + return "%s/%s/assets/thumbnail/%s" + } +} diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/application/EndToEndTestNetworkConfigModule.kt b/instrumentation/src/java/org/oppia/android/instrumentation/application/EndToEndTestNetworkConfigModule.kt new file mode 100644 index 00000000000..41d80126a13 --- /dev/null +++ b/instrumentation/src/java/org/oppia/android/instrumentation/application/EndToEndTestNetworkConfigModule.kt @@ -0,0 +1,29 @@ +package org.oppia.android.instrumentation.application + +import dagger.Module +import dagger.Provides +import org.oppia.android.data.backends.gae.BaseUrl +import org.oppia.android.data.backends.gae.XssiPrefix + +/** Provides network-specific constants needed to configure end-to-end tests. */ +@Module +class EndToEndTestNetworkConfigModule { + + /** Provides BaseUrl that connects to development server. */ + @Provides + @BaseUrl + fun provideNetworkBaseUrl(): String { + return "http://localhost:8181" + } + + /** + * Prefix in Json response for extra layer of security in API calls + * https://github.com/oppia/oppia/blob/8f9eed/feconf.py#L319 + * Remove this prefix from every Json response which is achieved in [NetworkInterceptor] + */ + @Provides + @XssiPrefix + fun provideXssiPrefix(): String { + return ")]}'" + } +} diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/application/OppiaTestApplication.kt b/instrumentation/src/java/org/oppia/android/instrumentation/application/OppiaTestApplication.kt new file mode 100644 index 00000000000..f57fb64d52c --- /dev/null +++ b/instrumentation/src/java/org/oppia/android/instrumentation/application/OppiaTestApplication.kt @@ -0,0 +1,43 @@ +package org.oppia.android.instrumentation.application + +import android.app.Application +import androidx.appcompat.app.AppCompatActivity +import androidx.multidex.MultiDexApplication +import androidx.work.Configuration +import androidx.work.WorkManager +import com.google.firebase.FirebaseApp +import org.oppia.android.app.activity.ActivityComponent +import org.oppia.android.app.application.ActivityComponentFactory +import org.oppia.android.app.application.ApplicationInjector +import org.oppia.android.app.application.ApplicationInjectorProvider +import org.oppia.android.domain.oppialogger.ApplicationStartupListener + +/** The root [Application] of the all end-to-end test apps. */ +class OppiaTestApplication : + MultiDexApplication(), + ActivityComponentFactory, + ApplicationInjectorProvider, + Configuration.Provider { + private val component: TestApplicationComponent by lazy { + DaggerTestApplicationComponent.builder() + .setApplication(this) + .build() + } + + override fun createActivityComponent(activity: AppCompatActivity): ActivityComponent { + return component.getActivityComponentBuilderProvider().get().setActivity(activity).build() + } + + override fun onCreate() { + super.onCreate() + FirebaseApp.initializeApp(applicationContext) + WorkManager.initialize(applicationContext, workManagerConfiguration) + component.getApplicationStartupListeners().forEach(ApplicationStartupListener::onCreate) + } + + override fun getApplicationInjector(): ApplicationInjector = component + + override fun getWorkManagerConfiguration(): Configuration { + return component.getWorkManagerConfiguration() + } +} diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt b/instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt new file mode 100644 index 00000000000..3f02025d2ee --- /dev/null +++ b/instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt @@ -0,0 +1,100 @@ +package org.oppia.android.instrumentation.application + +import android.app.Application +import androidx.work.Configuration +import dagger.BindsInstance +import dagger.Component +import org.oppia.android.app.activity.ActivityComponent +import org.oppia.android.app.application.ApplicationInjector +import org.oppia.android.app.application.ApplicationModule +import org.oppia.android.app.application.ApplicationStartupListenerModule +import org.oppia.android.app.devoptions.DeveloperOptionsModule +import org.oppia.android.app.devoptions.DeveloperOptionsStarterModule +import org.oppia.android.app.shim.IntentFactoryShimModule +import org.oppia.android.app.shim.ViewBindingShimModule +import org.oppia.android.app.topic.PracticeTabModule +import org.oppia.android.data.backends.gae.NetworkModule +import org.oppia.android.domain.classify.InteractionsModule +import org.oppia.android.domain.classify.rules.continueinteraction.ContinueModule +import org.oppia.android.domain.classify.rules.dragAndDropSortInput.DragDropSortInputModule +import org.oppia.android.domain.classify.rules.fractioninput.FractionInputModule +import org.oppia.android.domain.classify.rules.imageClickInput.ImageClickInputModule +import org.oppia.android.domain.classify.rules.itemselectioninput.ItemSelectionInputModule +import org.oppia.android.domain.classify.rules.multiplechoiceinput.MultipleChoiceInputModule +import org.oppia.android.domain.classify.rules.numberwithunits.NumberWithUnitsRuleModule +import org.oppia.android.domain.classify.rules.numericinput.NumericInputRuleModule +import org.oppia.android.domain.classify.rules.ratioinput.RatioInputModule +import org.oppia.android.domain.classify.rules.textinput.TextInputRuleModule +import org.oppia.android.domain.exploration.lightweightcheckpointing.ExplorationStorageModule +import org.oppia.android.domain.hintsandsolution.HintsAndSolutionConfigModule +import org.oppia.android.domain.hintsandsolution.HintsAndSolutionProdModule +import org.oppia.android.domain.onboarding.ExpirationMetaDataRetrieverModule +import org.oppia.android.domain.oppialogger.ApplicationStartupListener +import org.oppia.android.domain.oppialogger.LogStorageModule +import org.oppia.android.domain.oppialogger.exceptions.UncaughtExceptionLoggerModule +import org.oppia.android.domain.oppialogger.loguploader.LogUploadWorkerModule +import org.oppia.android.domain.oppialogger.loguploader.WorkManagerConfigurationModule +import org.oppia.android.domain.platformparameter.PlatformParameterModule +import org.oppia.android.domain.question.QuestionModule +import org.oppia.android.domain.topic.PrimeTopicAssetsControllerModule +import org.oppia.android.util.accessibility.AccessibilityProdModule +import org.oppia.android.util.caching.CachingModule +import org.oppia.android.util.logging.LoggerModule +import org.oppia.android.util.logging.firebase.DebugLogReportingModule +import org.oppia.android.util.logging.firebase.FirebaseLogUploaderModule +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.GlideImageLoaderModule +import org.oppia.android.util.system.OppiaClockModule +import org.oppia.android.util.threading.DispatcherModule +import javax.inject.Provider +import javax.inject.Singleton + +/** + * Root Dagger component for the test application. All application-scoped modules should be included + * in this component. + */ +@Singleton +@Component( + modules = [ + ApplicationModule::class, DispatcherModule::class, + LoggerModule::class, OppiaClockModule::class, + ContinueModule::class, FractionInputModule::class, + ItemSelectionInputModule::class, MultipleChoiceInputModule::class, + NumberWithUnitsRuleModule::class, NumericInputRuleModule::class, + TextInputRuleModule::class, DragDropSortInputModule::class, + InteractionsModule::class, EndToEndTestGcsResourceModule::class, + GlideImageLoaderModule::class, EndToEndTestImageParsingModule::class, + HtmlParserEntityTypeModule::class, CachingModule::class, + QuestionModule::class, DebugLogReportingModule::class, + AccessibilityProdModule::class, ImageClickInputModule::class, + LogStorageModule::class, IntentFactoryShimModule::class, + ViewBindingShimModule::class, PrimeTopicAssetsControllerModule::class, + ExpirationMetaDataRetrieverModule::class, RatioInputModule::class, + UncaughtExceptionLoggerModule::class, ApplicationStartupListenerModule::class, + LogUploadWorkerModule::class, WorkManagerConfigurationModule::class, + HintsAndSolutionConfigModule::class, HintsAndSolutionProdModule::class, + FirebaseLogUploaderModule::class, NetworkModule::class, PracticeTabModule::class, + PlatformParameterModule::class, ExplorationStorageModule::class, + DeveloperOptionsStarterModule::class, DeveloperOptionsModule::class, + NetworkConnectionUtilDebugModule::class, EndToEndTestNetworkConfigModule::class, + // TODO(#59): Remove this module once we completely migrate to Bazel from Gradle as we can then + // directly exclude debug files from the build and thus won't be requiring this module. + NetworkConnectionDebugUtilModule::class + ] +) +interface TestApplicationComponent : ApplicationInjector { + @Component.Builder + interface Builder { + @BindsInstance + fun setApplication(application: Application): Builder + fun build(): TestApplicationComponent + } + + fun getActivityComponentBuilderProvider(): Provider + + fun getApplicationStartupListeners(): Set + + fun getWorkManagerConfiguration(): Configuration +} diff --git a/instrumentation/src/java/org/oppia/android/instrumentation/testing/BUILD.bazel b/instrumentation/src/java/org/oppia/android/instrumentation/testing/BUILD.bazel index 17eb91b6c69..2ebb466bd56 100644 --- a/instrumentation/src/java/org/oppia/android/instrumentation/testing/BUILD.bazel +++ b/instrumentation/src/java/org/oppia/android/instrumentation/testing/BUILD.bazel @@ -10,7 +10,7 @@ kt_android_library( srcs = [ "EndToEndTestHelper.kt", ], - visibility = ["//:oppia_testing_visibility"], + visibility = ["//:oppia_e2e_testing_visibility"], deps = [ "//third_party:androidx_test_ext_junit", "//third_party:androidx_test_uiautomator_uiautomator", diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/application/BUILD.bazel b/instrumentation/src/javatests/org/oppia/android/instrumentation/application/BUILD.bazel new file mode 100644 index 00000000000..43b0a009e54 --- /dev/null +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/application/BUILD.bazel @@ -0,0 +1,59 @@ +""" +This library contains the Robolectric tests for the e2e test modules. +""" + +load("@dagger//:workspace_defs.bzl", "dagger_rules") +load("//:oppia_android_test.bzl", "oppia_android_test") + +oppia_android_test( + name = "EndToEndTestGcsResourceModuleTest", + srcs = ["EndToEndTestGcsResourceModuleTest.kt"], + custom_package = "org.oppia.android.instrumentation.application", + test_class = "org.oppia.android.instrumentation.application.EndToEndTestGcsResourceModuleTest", + test_manifest = "//testing:test_manifest", + deps = [ + ":dagger", + "//instrumentation/src/java/org/oppia/android/instrumentation/application:oppia_test_application", + "//third_party:androidx_test_ext_junit", + "//third_party:androidx_test_runner", + "//third_party:com_google_truth_truth", + "//third_party:org_robolectric_robolectric", + "//third_party:robolectric_android-all", + ], +) + +oppia_android_test( + name = "EndToEndTestImageParsingModuleTest", + srcs = ["EndToEndTestImageParsingModuleTest.kt"], + custom_package = "org.oppia.android.instrumentation.application", + test_class = "org.oppia.android.instrumentation.application.EndToEndTestImageParsingModuleTest", + test_manifest = "//testing:test_manifest", + deps = [ + ":dagger", + "//instrumentation/src/java/org/oppia/android/instrumentation/application:oppia_test_application", + "//third_party:androidx_test_ext_junit", + "//third_party:androidx_test_runner", + "//third_party:com_google_truth_truth", + "//third_party:org_robolectric_robolectric", + "//third_party:robolectric_android-all", + ], +) + +oppia_android_test( + name = "EndToEndTestNetworkConfigModuleTest", + srcs = ["EndToEndTestNetworkConfigModuleTest.kt"], + custom_package = "org.oppia.android.instrumentation.application", + test_class = "org.oppia.android.instrumentation.application.EndToEndTestNetworkConfigModuleTest", + test_manifest = "//testing:test_manifest", + deps = [ + ":dagger", + "//instrumentation/src/java/org/oppia/android/instrumentation/application:oppia_test_application", + "//third_party:androidx_test_ext_junit", + "//third_party:androidx_test_runner", + "//third_party:com_google_truth_truth", + "//third_party:org_robolectric_robolectric", + "//third_party:robolectric_android-all", + ], +) + +dagger_rules() diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/application/EndToEndTestGcsResourceModuleTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/application/EndToEndTestGcsResourceModuleTest.kt new file mode 100644 index 00000000000..da0b0529df6 --- /dev/null +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/application/EndToEndTestGcsResourceModuleTest.kt @@ -0,0 +1,91 @@ +package org.oppia.android.instrumentation.application + +import android.app.Application +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import dagger.BindsInstance +import dagger.Component +import dagger.Module +import dagger.Provides +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.oppia.android.util.gcsresource.DefaultResourceBucketName +import org.oppia.android.util.gcsresource.QuestionResourceBucketName +import org.robolectric.annotation.Config +import org.robolectric.annotation.LooperMode +import javax.inject.Inject +import javax.inject.Singleton + +@RunWith(AndroidJUnit4::class) +@LooperMode(LooperMode.Mode.PAUSED) +@Config(application = EndToEndTestGcsResourceModuleTest.TestApplication::class) +class EndToEndTestGcsResourceModuleTest { + + @field:[Inject DefaultResourceBucketName] + lateinit var defaultResourceBucketName: String + + @field:[Inject QuestionResourceBucketName] + lateinit var questionResourceBucketName: String + + @Before + fun setUp() { + setUpTestApplicationComponent() + } + + @Test + fun testModule_defaultGcsResource_isAssetsDevHandler() { + assertThat(defaultResourceBucketName).isEqualTo("assetsdevhandler") + } + + @Test + fun testModule_questionResourceBucketName_isAssetsDevHandler() { + assertThat(questionResourceBucketName).isEqualTo("assetsdevhandler") + } + + private fun setUpTestApplicationComponent() { + ApplicationProvider.getApplicationContext() + .inject(this) + } + + @Module + class TestModule { + @Provides + @Singleton + fun provideContext(application: Application): Context { + return application + } + } + + @Singleton + @Component( + modules = [ + TestModule::class, EndToEndTestGcsResourceModule::class + ] + ) + + interface TestApplicationComponent { + @Component.Builder + interface Builder { + @BindsInstance + fun setApplication(application: Application): Builder + fun build(): TestApplicationComponent + } + + fun inject(endTestGcsResourceModuleTest: EndToEndTestGcsResourceModuleTest) + } + + class TestApplication : Application() { + private val component: TestApplicationComponent by lazy { + DaggerEndToEndTestGcsResourceModuleTest_TestApplicationComponent.builder() + .setApplication(this) + .build() + } + + fun inject(endTestGcsResourceModuleTest: EndToEndTestGcsResourceModuleTest) { + component.inject(endTestGcsResourceModuleTest) + } + } +} diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/application/EndToEndTestImageParsingModuleTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/application/EndToEndTestImageParsingModuleTest.kt new file mode 100644 index 00000000000..34e16dfb090 --- /dev/null +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/application/EndToEndTestImageParsingModuleTest.kt @@ -0,0 +1,100 @@ +package org.oppia.android.instrumentation.application + +import android.app.Application +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import dagger.BindsInstance +import dagger.Component +import dagger.Module +import dagger.Provides +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.oppia.android.util.parser.image.DefaultGcsPrefix +import org.oppia.android.util.parser.image.ImageDownloadUrlTemplate +import org.oppia.android.util.parser.image.ThumbnailDownloadUrlTemplate +import org.robolectric.annotation.Config +import org.robolectric.annotation.LooperMode +import javax.inject.Inject +import javax.inject.Singleton + +@RunWith(AndroidJUnit4::class) +@LooperMode(LooperMode.Mode.PAUSED) +@Config(application = EndToEndTestImageParsingModuleTest.TestApplication::class) +class EndToEndTestImageParsingModuleTest { + + @field:[Inject DefaultGcsPrefix] + lateinit var defaultGcsPrefix: String + + @field:[Inject ImageDownloadUrlTemplate] + lateinit var imageDownloadUrlTemplate: String + + @field:[Inject ThumbnailDownloadUrlTemplate] + lateinit var thumbnailDownloadUrlTemplate: String + + @Before + fun setUp() { + setUpTestApplicationComponent() + } + + @Test + fun testModule_defaultGcsPrefix_isLocalHost() { + assertThat(defaultGcsPrefix).isEqualTo("http://localhost:8181/") + } + + @Test + fun testModule_imageDownloadUrlTemplate_isImageTemplate() { + assertThat(imageDownloadUrlTemplate).isEqualTo("%s/%s/assets/image/%s") + } + + @Test + fun testModule_thumbnailDownloadUrlTemplate_isThumbnailTemplate() { + assertThat(thumbnailDownloadUrlTemplate).isEqualTo("%s/%s/assets/thumbnail/%s") + } + + private fun setUpTestApplicationComponent() { + ApplicationProvider.getApplicationContext() + .inject(this) + } + + @Module + class TestModule { + @Provides + @Singleton + fun provideContext(application: Application): Context { + return application + } + } + + @Singleton + @Component( + modules = [ + TestModule::class, EndToEndTestImageParsingModule::class + ] + ) + + interface TestApplicationComponent { + @Component.Builder + interface Builder { + @BindsInstance + fun setApplication(application: Application): Builder + fun build(): TestApplicationComponent + } + + fun inject(endToEndTestImageParsingModuleTest: EndToEndTestImageParsingModuleTest) + } + + class TestApplication : Application() { + private val component: TestApplicationComponent by lazy { + DaggerEndToEndTestImageParsingModuleTest_TestApplicationComponent.builder() + .setApplication(this) + .build() + } + + fun inject(endToEndTestImageParsingModuleTest: EndToEndTestImageParsingModuleTest) { + component.inject(endToEndTestImageParsingModuleTest) + } + } +} diff --git a/instrumentation/src/javatests/org/oppia/android/instrumentation/application/EndToEndTestNetworkConfigModuleTest.kt b/instrumentation/src/javatests/org/oppia/android/instrumentation/application/EndToEndTestNetworkConfigModuleTest.kt new file mode 100644 index 00000000000..6718bc040ef --- /dev/null +++ b/instrumentation/src/javatests/org/oppia/android/instrumentation/application/EndToEndTestNetworkConfigModuleTest.kt @@ -0,0 +1,91 @@ +package org.oppia.android.instrumentation.application + +import android.app.Application +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import dagger.BindsInstance +import dagger.Component +import dagger.Module +import dagger.Provides +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.oppia.android.data.backends.gae.BaseUrl +import org.oppia.android.data.backends.gae.XssiPrefix +import org.robolectric.annotation.Config +import org.robolectric.annotation.LooperMode +import javax.inject.Inject +import javax.inject.Singleton + +@RunWith(AndroidJUnit4::class) +@LooperMode(LooperMode.Mode.PAUSED) +@Config(application = EndToEndTestNetworkConfigModuleTest.TestApplication::class) +class EndToEndTestNetworkConfigModuleTest { + + @field:[Inject BaseUrl] + lateinit var baseUrl: String + + @field:[Inject XssiPrefix] + lateinit var xssiPrefix: String + + @Before + fun setUp() { + setUpTestApplicationComponent() + } + + @Test + fun testModule_baseUrl_isLocalhost() { + assertThat(baseUrl).isEqualTo("http://localhost:8181") + } + + @Test + fun testModule_xssiPrefix_isXssiPrefix() { + assertThat(xssiPrefix).isEqualTo(")]}'") + } + + private fun setUpTestApplicationComponent() { + ApplicationProvider.getApplicationContext() + .inject(this) + } + + @Module + class TestModule { + @Provides + @Singleton + fun provideContext(application: Application): Context { + return application + } + } + + @Singleton + @Component( + modules = [ + TestModule::class, EndToEndTestNetworkConfigModule::class + ] + ) + + interface TestApplicationComponent { + @Component.Builder + interface Builder { + @BindsInstance + fun setApplication(application: Application): Builder + fun build(): TestApplicationComponent + } + + fun inject(endTestNetworkConfigModuleTest: EndToEndTestNetworkConfigModuleTest) + } + + class TestApplication : Application() { + private val component: TestApplicationComponent by lazy { + DaggerEndToEndTestNetworkConfigModuleTest_TestApplicationComponent.builder() + .setApplication(this) + .build() + } + + fun inject(endToEndTestNetworkConfigModuleTest: EndToEndTestNetworkConfigModuleTest) { + component.inject(endToEndTestNetworkConfigModuleTest) + } + } +} diff --git a/scripts/assets/kdoc_validity_exemptions.textproto b/scripts/assets/kdoc_validity_exemptions.textproto index 3c271b9dfd1..cfd53b636b3 100644 --- a/scripts/assets/kdoc_validity_exemptions.textproto +++ b/scripts/assets/kdoc_validity_exemptions.textproto @@ -360,7 +360,6 @@ exempted_file_path: "app/src/sharedTest/java/org/oppia/android/app/utility/Orien exempted_file_path: "app/src/sharedTest/java/org/oppia/android/app/utility/TabMatcher.kt" exempted_file_path: "app/src/test/java/org/oppia/android/app/testing/ProfileProgressSpanCount.kt" exempted_file_path: "app/src/test/java/org/oppia/android/app/testing/player/split/PlayerSplitScreenTesting.kt" -exempted_file_path: "data/src/main/java/org/oppia/android/data/backends/gae/NetworkSettings.kt" exempted_file_path: "data/src/main/java/org/oppia/android/data/backends/gae/api/ClassroomService.kt" exempted_file_path: "data/src/main/java/org/oppia/android/data/backends/gae/api/ConceptCardService.kt" exempted_file_path: "data/src/main/java/org/oppia/android/data/backends/gae/api/ExplorationService.kt" @@ -391,6 +390,7 @@ exempted_file_path: "domain/src/main/java/org/oppia/android/domain/topic/TopicCo exempted_file_path: "domain/src/main/java/org/oppia/android/domain/topic/TopicListController.kt" exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/JsonAssetRetriever.kt" exempted_file_path: "domain/src/test/java/org/oppia/android/domain/classify/InteractionObjectTestBuilder.kt" +exempted_file_path: "instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt" exempted_file_path: "testing/src/main/java/org/oppia/android/testing/RichTextViewMatcher.kt" exempted_file_path: "testing/src/main/java/org/oppia/android/testing/espresso/ImageViewMatcher.kt" exempted_file_path: "testing/src/main/java/org/oppia/android/testing/lightweightcheckpointing/ExplorationCheckpointTestHelper.kt" diff --git a/scripts/assets/test_file_exemptions.textproto b/scripts/assets/test_file_exemptions.textproto index 9bfd7659635..1d62cc76509 100644 --- a/scripts/assets/test_file_exemptions.textproto +++ b/scripts/assets/test_file_exemptions.textproto @@ -481,11 +481,12 @@ exempted_file_path: "app/src/sharedTest/java/org/oppia/android/app/utility/Progr exempted_file_path: "app/src/sharedTest/java/org/oppia/android/app/utility/TabMatcher.kt" exempted_file_path: "app/src/test/java/org/oppia/android/app/testing/ProfileProgressSpanCount.kt" exempted_file_path: "app/src/test/java/org/oppia/android/app/testing/player/split/PlayerSplitScreenTesting.kt" +exempted_file_path: "data/src/main/java/org/oppia/android/data/backends/gae/BaseUrl.kt" exempted_file_path: "data/src/main/java/org/oppia/android/data/backends/gae/Constants.kt" exempted_file_path: "data/src/main/java/org/oppia/android/data/backends/gae/NetworkApiKey.kt" exempted_file_path: "data/src/main/java/org/oppia/android/data/backends/gae/NetworkModule.kt" -exempted_file_path: "data/src/main/java/org/oppia/android/data/backends/gae/NetworkSettings.kt" exempted_file_path: "data/src/main/java/org/oppia/android/data/backends/gae/OppiaRetrofit.kt" +exempted_file_path: "data/src/main/java/org/oppia/android/data/backends/gae/XssiPrefix.kt" exempted_file_path: "data/src/main/java/org/oppia/android/data/backends/gae/model/GaeAnswerGroup.kt" exempted_file_path: "data/src/main/java/org/oppia/android/data/backends/gae/model/GaeClassroom.kt" exempted_file_path: "data/src/main/java/org/oppia/android/data/backends/gae/model/GaeConceptCard.kt" @@ -586,6 +587,8 @@ exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/FloatExt exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/FractionExtensions.kt" exempted_file_path: "domain/src/main/java/org/oppia/android/domain/util/JsonAssetRetriever.kt" exempted_file_path: "domain/src/test/java/org/oppia/android/domain/classify/InteractionObjectTestBuilder.kt" +exempted_file_path: "instrumentation/src/java/org/oppia/android/instrumentation/application/OppiaTestApplication.kt" +exempted_file_path: "instrumentation/src/java/org/oppia/android/instrumentation/application/TestApplicationComponent.kt" exempted_file_path: "instrumentation/src/java/org/oppia/android/instrumentation/testing/EndToEndTestHelper.kt" exempted_file_path: "scripts/src/java/org/oppia/android/scripts/common/CommandExecutor.kt" exempted_file_path: "scripts/src/java/org/oppia/android/scripts/common/CommandResult.kt" diff --git a/scripts/src/java/org/oppia/android/scripts/testing/TestBazelWorkspace.kt b/scripts/src/java/org/oppia/android/scripts/testing/TestBazelWorkspace.kt index 4f2bdf07431..c86567477a6 100644 --- a/scripts/src/java/org/oppia/android/scripts/testing/TestBazelWorkspace.kt +++ b/scripts/src/java/org/oppia/android/scripts/testing/TestBazelWorkspace.kt @@ -67,10 +67,10 @@ class TestBazelWorkspace(private val temporaryRootFolder: TemporaryFolder) { createLibrary("${testName}Dependency") } else null to listOf() val buildFile = if (subpackage != null) { - if (!File(temporaryRootFolder.root, subpackage).exists()) { - temporaryRootFolder.newFolder(subpackage) + if (!File(temporaryRootFolder.root, subpackage.replace(".", "/")).exists()) { + temporaryRootFolder.newFolder(*(subpackage.split(".")).toTypedArray()) } - val newBuildFile = temporaryRootFolder.newFile("$subpackage/BUILD.bazel") + val newBuildFile = temporaryRootFolder.newFile("${subpackage.replace(".", "/")}/BUILD.bazel") newBuildFile } else rootBuildFile prepareBuildFileForTests(buildFile) @@ -108,10 +108,10 @@ class TestBazelWorkspace(private val temporaryRootFolder: TemporaryFolder) { ): Iterable { check(testName !in testFileMap) { "Test '$testName' already exists" } val testFile = if (subpackage != null) { - if (!File(temporaryRootFolder.root, subpackage).exists()) { - temporaryRootFolder.newFolder(subpackage) + if (!File(temporaryRootFolder.root, subpackage.replace(".", "/")).exists()) { + temporaryRootFolder.newFolder(*(subpackage.split(".")).toTypedArray()) } - temporaryRootFolder.newFile("$subpackage/$testName.kt") + temporaryRootFolder.newFile("${subpackage.replace(".", "/")}/$testName.kt") } else temporaryRootFolder.newFile("$testName.kt") return addTestToBuildFile( testName, diff --git a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt index b9fe491ace6..c70b453f3d0 100644 --- a/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt +++ b/scripts/src/javatests/org/oppia/android/scripts/ci/ComputeAffectedTestsTest.kt @@ -287,6 +287,10 @@ class ComputeAffectedTestsTest { "InstrumentationTest", subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.player" ) + createBasicTests( + "RobolectricTest", + subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.app" + ) createBasicTests("ThirdTest") val reportedTargets = runScript() @@ -295,6 +299,11 @@ class ComputeAffectedTestsTest { ).doesNotContain( "//instrumentation/src/javatests/org/oppia/android/instrumentation/player:InstrumentationTest" ) + assertThat( + reportedTargets + ).contains( + "//instrumentation/src/javatests/org/oppia/android/instrumentation/app:RobolectricTest" + ) } @Test @@ -307,7 +316,7 @@ class ComputeAffectedTestsTest { ) createBasicTests( "RobolectricTest", - subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.application" + subpackage = "instrumentation.src.javatests.org.oppia.android.instrumentation.app" ) val reportedTargets = runScript() @@ -316,6 +325,11 @@ class ComputeAffectedTestsTest { ).doesNotContain( "//instrumentation/src/javatests/org/oppia/android/instrumentation/player:InstrumentationTest" ) + assertThat( + reportedTargets + ).contains( + "//instrumentation/src/javatests/org/oppia/android/instrumentation/app:RobolectricTest" + ) } /** diff --git a/scripts/src/javatests/org/oppia/android/scripts/testing/TestBazelWorkspaceTest.kt b/scripts/src/javatests/org/oppia/android/scripts/testing/TestBazelWorkspaceTest.kt index 7f061e036f3..3700f414110 100644 --- a/scripts/src/javatests/org/oppia/android/scripts/testing/TestBazelWorkspaceTest.kt +++ b/scripts/src/javatests/org/oppia/android/scripts/testing/TestBazelWorkspaceTest.kt @@ -450,6 +450,24 @@ class TestBazelWorkspaceTest { .containsExactly("WORKSPACE", "subpackage/BUILD.bazel", "subpackage/FirstTest.kt") } + @Test + fun testAddTestToBuildFile_unusedTestName_withMultipleSubpackages_returnsNewBuildAndTestFiles() { + val testBazelWorkspace = TestBazelWorkspace(tempFolder) + testBazelWorkspace.initEmptyWorkspace() + val subpackage = "subpackage.first.second" + tempFolder.newFolder(*(subpackage.split(".")).toTypedArray()) + val files = testBazelWorkspace.addTestToBuildFile( + testName = "FirstTest", + testFile = tempFolder.newFile("subpackage/first/second/FirstTest.kt"), + subpackage = subpackage + ) + + assertThat(files.getRelativeFileNames(tempFolder.root)) + .containsExactly( + "WORKSPACE", "subpackage/first/second/BUILD.bazel", "subpackage/first/second/FirstTest.kt" + ) + } + @Test fun testAddTestToBuildFile_unusedTestName_withGeneratedAndExtraDeps_includesBothInTestDeps() { val testBazelWorkspace = TestBazelWorkspace(tempFolder) @@ -661,6 +679,22 @@ class TestBazelWorkspaceTest { .containsExactly("WORKSPACE", "subpackage/BUILD.bazel", "subpackage/FirstTest.kt") } + @Test + fun testCreateTest_unusedTestName_withMultipleSubpackages_returnsNewBuildAndTestFiles() { + val testBazelWorkspace = TestBazelWorkspace(tempFolder) + testBazelWorkspace.initEmptyWorkspace() + + val files = testBazelWorkspace.createTest( + testName = "FirstTest", + subpackage = "subpackage.first.second" + ) + + assertThat(files.getRelativeFileNames(tempFolder.root)) + .containsExactly( + "WORKSPACE", "subpackage/first/second/BUILD.bazel", "subpackage/first/second/FirstTest.kt" + ) + } + @Test fun testCreateTest_unusedTestName_withGeneratedAndExtraDeps_includesBothInTestDeps() { val testBazelWorkspace = TestBazelWorkspace(tempFolder) diff --git a/testing/BUILD.bazel b/testing/BUILD.bazel index 97438b9bbe4..c57d9e81d61 100644 --- a/testing/BUILD.bazel +++ b/testing/BUILD.bazel @@ -64,6 +64,7 @@ TEST_DEPS = [ ":assertion_helpers", ":dagger", ":testing", + "//data/src/main/java/org/oppia/android/data/backends/gae:network_config_prod_module", "//domain", "//testing/src/main/java/org/oppia/android/testing/network", "//testing/src/main/java/org/oppia/android/testing/network:test_module", diff --git a/testing/src/main/java/org/oppia/android/testing/network/BUILD.bazel b/testing/src/main/java/org/oppia/android/testing/network/BUILD.bazel index a20d1a4b0fe..2625e752560 100644 --- a/testing/src/main/java/org/oppia/android/testing/network/BUILD.bazel +++ b/testing/src/main/java/org/oppia/android/testing/network/BUILD.bazel @@ -24,7 +24,6 @@ kt_android_library( deps = [ ":impl", "//data/src/main/java/org/oppia/android/data/backends/gae:network_interceptors", - "//data/src/main/java/org/oppia/android/data/backends/gae:network_settings", "//data/src/main/java/org/oppia/android/data/backends/gae/api", "//data/src/main/java/org/oppia/android/data/backends/gae/model", "//testing/src/main/java/org/oppia/android/testing/platformparameter:test_constants", diff --git a/testing/src/main/java/org/oppia/android/testing/network/MockClassroomService.kt b/testing/src/main/java/org/oppia/android/testing/network/MockClassroomService.kt index 22e67fe1335..0766c1812e8 100755 --- a/testing/src/main/java/org/oppia/android/testing/network/MockClassroomService.kt +++ b/testing/src/main/java/org/oppia/android/testing/network/MockClassroomService.kt @@ -3,7 +3,6 @@ package org.oppia.android.testing.network import com.squareup.moshi.JsonAdapter import com.squareup.moshi.Moshi import org.oppia.android.data.backends.gae.JsonPrefixNetworkInterceptor -import org.oppia.android.data.backends.gae.NetworkSettings import org.oppia.android.data.backends.gae.api.ClassroomService import org.oppia.android.data.backends.gae.model.GaeClassroom import retrofit2.Call @@ -12,8 +11,10 @@ import retrofit2.mock.BehaviorDelegate /** * Mock ClassroomService with dummy data from [classroom.json] */ -class MockClassroomService(private val delegate: BehaviorDelegate) : - ClassroomService { +class MockClassroomService( + private val delegate: BehaviorDelegate, + private val xssiPrefix: String +) : ClassroomService { override fun getClassroom(classroomName: String): Call { val classroom = createMockGaeClassroom() return delegate.returningResponse(classroom).getClassroom(classroomName) @@ -24,9 +25,9 @@ class MockClassroomService(private val delegate: BehaviorDelegate) : - ConceptCardService { +class MockConceptCardService( + private val delegate: BehaviorDelegate, + private val xssiPrefix: String +) : ConceptCardService { override fun getSkillContents(skillIds: String): Call { val conceptCard = createMockGaeConceptCard() return delegate.returningResponse(conceptCard).getSkillContents(skillIds) @@ -24,9 +25,9 @@ class MockConceptCardService(private val delegate: BehaviorDelegate) : - ExplorationService { +class MockExplorationService( + private val delegate: BehaviorDelegate, + private val xssiPrefix: String +) : ExplorationService { override fun getExplorationById(explorationId: String): Call { val explorationContainer = createMockGaeExplorationContainer() return delegate.returningResponse(explorationContainer).getExplorationById(explorationId) @@ -24,9 +25,9 @@ class MockExplorationService(private val delegate: BehaviorDelegate) : - QuestionPlayerService { +class MockQuestionPlayerService( + private val delegate: BehaviorDelegate, + private val xssiPrefix: String +) : QuestionPlayerService { override fun getQuestionPlayerBySkillIds( skillIds: String, questionCount: Int @@ -28,9 +29,9 @@ class MockQuestionPlayerService(private val delegate: BehaviorDelegate) : StoryService { +class MockStoryService( + private val delegate: BehaviorDelegate, + private val xssiPrefix: String +) : StoryService { override fun getStory(storyId: String, userId: String?, user: String?): Call { val story = createMockGaeStory() return delegate.returningResponse(story).getStory(storyId, userId, user) @@ -23,9 +25,9 @@ class MockStoryService(private val delegate: BehaviorDelegate) : S * @return GaeStory: GaeStory with mock data */ private fun createMockGaeStory(): GaeStory { - val networkInterceptor = JsonPrefixNetworkInterceptor() + val networkInterceptor = JsonPrefixNetworkInterceptor(xssiPrefix) var storyResponseWithXssiPrefix = - NetworkSettings.XSSI_PREFIX + ApiMockLoader.getFakeJson("story.json") + xssiPrefix + ApiMockLoader.getFakeJson("story.json") storyResponseWithXssiPrefix = networkInterceptor.removeXssiPrefix(storyResponseWithXssiPrefix) diff --git a/testing/src/main/java/org/oppia/android/testing/network/MockSubtopicService.kt b/testing/src/main/java/org/oppia/android/testing/network/MockSubtopicService.kt index 4368598a042..96a66b7858a 100644 --- a/testing/src/main/java/org/oppia/android/testing/network/MockSubtopicService.kt +++ b/testing/src/main/java/org/oppia/android/testing/network/MockSubtopicService.kt @@ -3,7 +3,6 @@ package org.oppia.android.testing.network import com.squareup.moshi.JsonAdapter import com.squareup.moshi.Moshi import org.oppia.android.data.backends.gae.JsonPrefixNetworkInterceptor -import org.oppia.android.data.backends.gae.NetworkSettings import org.oppia.android.data.backends.gae.api.SubtopicService import org.oppia.android.data.backends.gae.model.GaeSubtopic import retrofit2.Call @@ -12,8 +11,10 @@ import retrofit2.mock.BehaviorDelegate /** * Mock SubtopicService with dummy data from [subtopic.json] */ -class MockSubtopicService(private val delegate: BehaviorDelegate) : - SubtopicService { +class MockSubtopicService( + private val delegate: BehaviorDelegate, + private val xssiPrefix: String +) : SubtopicService { override fun getSubtopic(topicName: String, subtopicId: String): Call { val subtopic = createMockGaeSubtopic() return delegate.returningResponse(subtopic).getSubtopic(topicName, subtopicId) @@ -24,9 +25,9 @@ class MockSubtopicService(private val delegate: BehaviorDelegate) : TopicService { +class MockTopicService( + private val delegate: BehaviorDelegate, + private val xssiPrefix: String +) : TopicService { override fun getTopicByName(topicName: String): Call { val topic = createMockGaeTopic() return delegate.returningResponse(topic).getTopicByName(topicName) @@ -23,9 +25,9 @@ class MockTopicService(private val delegate: BehaviorDelegate) : T * @return GaeTopic: GaeTopic with mock data */ private fun createMockGaeTopic(): GaeTopic { - val networkInterceptor = JsonPrefixNetworkInterceptor() + val networkInterceptor = JsonPrefixNetworkInterceptor(xssiPrefix) var topicResponseWithXssiPrefix = - NetworkSettings.XSSI_PREFIX + ApiMockLoader.getFakeJson("topic.json") + xssiPrefix + ApiMockLoader.getFakeJson("topic.json") topicResponseWithXssiPrefix = networkInterceptor.removeXssiPrefix(topicResponseWithXssiPrefix) diff --git a/testing/src/test/java/org/oppia/android/testing/network/MockPlatformParameterServiceTest.kt b/testing/src/test/java/org/oppia/android/testing/network/MockPlatformParameterServiceTest.kt index bd380937b00..45922008e74 100644 --- a/testing/src/test/java/org/oppia/android/testing/network/MockPlatformParameterServiceTest.kt +++ b/testing/src/test/java/org/oppia/android/testing/network/MockPlatformParameterServiceTest.kt @@ -12,6 +12,7 @@ import dagger.Provides import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.oppia.android.data.backends.gae.NetworkConfigProdModule import org.oppia.android.data.backends.gae.NetworkModule import org.oppia.android.data.backends.gae.api.PlatformParameterService import org.oppia.android.testing.platformparameter.TEST_BOOLEAN_PARAM_NAME @@ -110,7 +111,8 @@ class MockPlatformParameterServiceTest { @Singleton @Component( modules = [ - TestModule::class, NetworkModule::class, RetrofitTestModule::class + TestModule::class, NetworkModule::class, + RetrofitTestModule::class, NetworkConfigProdModule::class ] ) interface TestApplicationComponent {