diff --git a/coreexample/src/androidTestMock/kotlin/me/proton/core/test/android/uitests/BaseMockTest.kt b/coreexample/src/androidTestMock/kotlin/me/proton/core/test/android/uitests/BaseMockTest.kt
new file mode 100644
index 000000000..4bd2e42d5
--- /dev/null
+++ b/coreexample/src/androidTestMock/kotlin/me/proton/core/test/android/uitests/BaseMockTest.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2022 Proton Technologies AG
+ * This file is part of Proton AG and ProtonCore.
+ *
+ * ProtonCore is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ProtonCore is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with ProtonCore. If not, see .
+ */
+
+package me.proton.core.test.android.uitests
+
+import dagger.hilt.android.testing.BindValue
+import dagger.hilt.android.testing.HiltAndroidTest
+import me.proton.core.network.data.di.BaseProtonApiUrl
+import okhttp3.HttpUrl
+import org.junit.Rule
+
+interface BaseMockTest {
+ @BaseProtonApiUrl
+ var baseProtonApiUrl: HttpUrl
+
+ val testUsername get() = "test-mock-936"
+ val testPassword get() = "password"
+}
+
+/** A minimal example for writing a test with hilt-testing and mocked server. */
+@HiltAndroidTest
+class SampleMockTest : BaseMockTest {
+ @get:Rule
+ val mockTestRule = MockTestRule(this)
+
+ @BindValue
+ @BaseProtonApiUrl
+ override lateinit var baseProtonApiUrl: HttpUrl
+}
diff --git a/coreexample/src/androidTestMock/kotlin/me/proton/core/test/android/uitests/MockTestRule.kt b/coreexample/src/androidTestMock/kotlin/me/proton/core/test/android/uitests/MockTestRule.kt
new file mode 100644
index 000000000..04ff1b9ec
--- /dev/null
+++ b/coreexample/src/androidTestMock/kotlin/me/proton/core/test/android/uitests/MockTestRule.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2022 Proton Technologies AG
+ * This file is part of Proton AG and ProtonCore.
+ *
+ * ProtonCore is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ProtonCore is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with ProtonCore. If not, see .
+ */
+
+package me.proton.core.test.android.uitests
+
+import dagger.hilt.android.testing.HiltAndroidRule
+import me.proton.android.core.coreexample.CoreExampleLogger
+import me.proton.core.test.android.TestWebServerDispatcher
+import me.proton.core.test.android.instrumented.utils.Shell
+import me.proton.core.util.kotlin.CoreLogger
+import okhttp3.mockwebserver.MockWebServer
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+import timber.log.Timber
+
+/** A test rule that applies [HiltAndroidRule] and prepares a mock [MockWebServer].
+ * @see SampleMockTest
+ */
+class MockTestRule constructor(private val testInstance: BaseMockTest) : TestRule {
+ lateinit var dispatcher: TestWebServerDispatcher
+
+ override fun apply(base: Statement, description: Description): Statement {
+ initLogging()
+
+ dispatcher = TestWebServerDispatcher()
+ val webServer = MockWebServer()
+ webServer.dispatcher = dispatcher
+
+ val hiltRule = HiltAndroidRule(testInstance)
+ val result = hiltRule.apply(object : Statement() {
+ override fun evaluate() {
+ testInstance.baseProtonApiUrl = webServer.url("/")
+ hiltRule.inject()
+ base.evaluate()
+ }
+ }, description)
+
+ return object : Statement() {
+ override fun evaluate() {
+ try {
+ result.evaluate()
+ } catch (t: Throwable) {
+ Shell.saveToFile(description)
+ throw t
+ } finally {
+ webServer.shutdown()
+ }
+ }
+ }
+ }
+
+ private fun initLogging() {
+ Timber.plant(Timber.DebugTree())
+ CoreLogger.set(CoreExampleLogger())
+ }
+}
diff --git a/coreexample/src/androidTestMock/kotlin/me/proton/core/test/android/uitests/giap/GiapUpgradeTests.kt b/coreexample/src/androidTestMock/kotlin/me/proton/core/test/android/uitests/giap/GiapUpgradeTests.kt
index 6a10a2cd0..181a1c068 100644
--- a/coreexample/src/androidTestMock/kotlin/me/proton/core/test/android/uitests/giap/GiapUpgradeTests.kt
+++ b/coreexample/src/androidTestMock/kotlin/me/proton/core/test/android/uitests/giap/GiapUpgradeTests.kt
@@ -21,9 +21,7 @@ package me.proton.core.test.android.uitests.giap
import androidx.test.core.app.ActivityScenario
import com.android.billingclient.api.BillingClient
import dagger.hilt.android.testing.BindValue
-import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
-import me.proton.android.core.coreexample.CoreExampleLogger
import me.proton.android.core.coreexample.MainActivity
import me.proton.core.network.data.di.BaseProtonApiUrl
import me.proton.core.test.android.TestWebServerDispatcher
@@ -31,55 +29,30 @@ import me.proton.core.test.android.mocks.FakeBillingClientFactory
import me.proton.core.test.android.mocks.mockBillingClientSuccess
import me.proton.core.test.android.robots.auth.AddAccountRobot
import me.proton.core.test.android.robots.payments.GoogleIAPRobot
+import me.proton.core.test.android.uitests.BaseMockTest
import me.proton.core.test.android.uitests.CoreexampleRobot
-import me.proton.core.util.kotlin.CoreLogger
+import me.proton.core.test.android.uitests.MockTestRule
import okhttp3.HttpUrl
-import okhttp3.mockwebserver.MockWebServer
import org.junit.Rule
-import timber.log.Timber
import javax.inject.Inject
-import kotlin.test.AfterTest
-import kotlin.test.BeforeTest
import kotlin.test.Test
import me.proton.core.test.android.plugins.data.Plan as TestPlan
@HiltAndroidTest
-class GiapUpgradeTests {
- private val testUsername = "test-mock-936"
- private val testPassword = "password"
-
- @get:Rule(order = Rule.DEFAULT_ORDER - 1)
- val hiltAndroidRule = HiltAndroidRule(this)
+class GiapUpgradeTests: BaseMockTest {
+ @get:Rule
+ val mockTestRule = MockTestRule(this)
@BindValue
@BaseProtonApiUrl
- lateinit var baseProtonApiUrl: HttpUrl
+ override lateinit var baseProtonApiUrl: HttpUrl
@Inject
lateinit var billingClientFactory: FakeBillingClientFactory
private val billingClient: BillingClient get() = billingClientFactory.billingClient
- private lateinit var dispatcher: TestWebServerDispatcher
- private lateinit var webServer: MockWebServer
- @BeforeTest
- fun setUp() {
- Timber.plant(Timber.DebugTree())
- CoreLogger.set(CoreExampleLogger())
-
- dispatcher = TestWebServerDispatcher()
- webServer = MockWebServer().apply {
- dispatcher = this@GiapUpgradeTests.dispatcher
- }
- baseProtonApiUrl = webServer.url("/")
-
- hiltAndroidRule.inject()
- }
-
- @AfterTest
- fun tearDown() {
- webServer.shutdown()
- }
+ private val dispatcher: TestWebServerDispatcher get() = mockTestRule.dispatcher
@Test
fun freeUserUpgradeAllProvidersAvailable() {
diff --git a/coreexample/src/androidTestMock/kotlin/me/proton/core/test/android/uitests/giap/SignupWithGoogleIapTests.kt b/coreexample/src/androidTestMock/kotlin/me/proton/core/test/android/uitests/giap/SignupWithGoogleIapTests.kt
index c91468d8c..02fa75e49 100644
--- a/coreexample/src/androidTestMock/kotlin/me/proton/core/test/android/uitests/giap/SignupWithGoogleIapTests.kt
+++ b/coreexample/src/androidTestMock/kotlin/me/proton/core/test/android/uitests/giap/SignupWithGoogleIapTests.kt
@@ -24,9 +24,7 @@ import androidx.test.core.app.ApplicationProvider
import com.android.billingclient.api.BillingClient
import com.android.billingclient.api.BillingClient.BillingResponseCode
import dagger.hilt.android.testing.BindValue
-import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
-import me.proton.android.core.coreexample.CoreExampleLogger
import me.proton.core.auth.presentation.ui.AddAccountActivity
import me.proton.core.network.data.di.BaseProtonApiUrl
import me.proton.core.plan.presentation.entity.PlanInput
@@ -41,56 +39,30 @@ import me.proton.core.test.android.robots.auth.signup.RecoveryMethodsRobot
import me.proton.core.test.android.robots.auth.signup.SignupFinishedRobot
import me.proton.core.test.android.robots.payments.GoogleIAPRobot
import me.proton.core.test.android.robots.plans.SelectPlanRobot
-import me.proton.core.util.kotlin.CoreLogger
+import me.proton.core.test.android.uitests.BaseMockTest
+import me.proton.core.test.android.uitests.MockTestRule
import okhttp3.HttpUrl
-import okhttp3.mockwebserver.MockWebServer
import org.junit.Rule
-import timber.log.Timber
import javax.inject.Inject
-import kotlin.test.AfterTest
-import kotlin.test.BeforeTest
import kotlin.test.Test
import me.proton.core.paymentiap.presentation.R as PaymentIapR
import me.proton.core.test.android.plugins.data.Plan as TestPlan
@HiltAndroidTest
-class SignupWithGoogleIapTests {
- private val testUsername = "test-mock-936"
- private val testPassword = "password"
-
- @get:Rule(order = Rule.DEFAULT_ORDER - 1)
- val hiltAndroidRule = HiltAndroidRule(this)
+class SignupWithGoogleIapTests : BaseMockTest {
+ @get:Rule
+ val mockTestRule = MockTestRule(this)
@BindValue
@BaseProtonApiUrl
- lateinit var baseProtonApiUrl: HttpUrl
+ override lateinit var baseProtonApiUrl: HttpUrl
@Inject
lateinit var billingClientFactory: FakeBillingClientFactory
private val appContext: Context get() = ApplicationProvider.getApplicationContext()
private val billingClient: BillingClient get() = billingClientFactory.billingClient
- private lateinit var dispatcher: TestWebServerDispatcher
- private lateinit var webServer: MockWebServer
-
- @BeforeTest
- fun setUp() {
- Timber.plant(Timber.DebugTree())
- CoreLogger.set(CoreExampleLogger())
-
- dispatcher = TestWebServerDispatcher()
- webServer = MockWebServer().apply {
- dispatcher = this@SignupWithGoogleIapTests.dispatcher
- }
- baseProtonApiUrl = webServer.url("/")
-
- hiltAndroidRule.inject()
- }
-
- @AfterTest
- fun tearDown() {
- webServer.shutdown()
- }
+ private val dispatcher: TestWebServerDispatcher get() = mockTestRule.dispatcher
@Test
fun googleBillingNotAvailable() {
@@ -137,6 +109,13 @@ class SignupWithGoogleIapTests {
.skipConfirm()
.toggleExpandPlan(TestPlan.Plus)
.selectPlan(TestPlan.Plus)
+ .apply {
+ verify {
+ payWithGoogleButtonIsClickable()
+ payWithCardButtonIsNotVisible()
+ switchPaymentProviderButtonIsNotVisible()
+ }
+ }
.payWithGPay()
.verify {
signupFinishedDisplayed()
@@ -169,6 +148,13 @@ class SignupWithGoogleIapTests {
.skipConfirm()
.toggleExpandPlan(TestPlan.Plus)
.selectPlan(TestPlan.Plus)
+ .apply {
+ verify {
+ payWithGoogleButtonIsClickable()
+ payWithCardButtonIsNotVisible()
+ switchPaymentProviderButtonIsVisible()
+ }
+ }
.payWithGPay()
.verify {
signupFinishedDisplayed()
diff --git a/test/android/instrumented/api/test-android-instrumented.api b/test/android/instrumented/api/test-android-instrumented.api
index a0c479bbb..f6504e58b 100644
--- a/test/android/instrumented/api/test-android-instrumented.api
+++ b/test/android/instrumented/api/test-android-instrumented.api
@@ -1063,6 +1063,8 @@ public final class me/proton/core/test/android/robots/payments/GoogleIAPRobot$Ve
public fun ()V
public final fun payWithCardButtonIsNotVisible ()V
public final fun payWithGoogleButtonIsClickable ()V
+ public final fun switchPaymentProviderButtonIsNotVisible ()V
+ public final fun switchPaymentProviderButtonIsVisible ()V
}
public class me/proton/core/test/android/robots/payments/PaymentRobot : me/proton/core/test/android/robots/CoreRobot {
diff --git a/test/android/instrumented/src/main/kotlin/me/proton/core/test/android/robots/payments/GoogleIAPRobot.kt b/test/android/instrumented/src/main/kotlin/me/proton/core/test/android/robots/payments/GoogleIAPRobot.kt
index 3b70ed32c..c7ab8a954 100644
--- a/test/android/instrumented/src/main/kotlin/me/proton/core/test/android/robots/payments/GoogleIAPRobot.kt
+++ b/test/android/instrumented/src/main/kotlin/me/proton/core/test/android/robots/payments/GoogleIAPRobot.kt
@@ -37,6 +37,14 @@ class GoogleIAPRobot : PaymentRobot() {
view.withId(R.id.payButton).checkNotDisplayed()
}
+ fun switchPaymentProviderButtonIsNotVisible() {
+ view.withId(R.id.nextPaymentProviderButton).checkNotDisplayed()
+ }
+
+ fun switchPaymentProviderButtonIsVisible() {
+ view.withId(R.id.nextPaymentProviderButton).checkDisplayed()
+ }
+
fun payWithGoogleButtonIsClickable() {
view.withId(R.id.gPayButton)
.checkDisplayed()