mirror of
https://github.com/ProtonMail/protoncore_android.git
synced 2026-06-14 09:54:49 +00:00
test(payment, plan): Fix plan UI tests for dynamic plans.
This commit is contained in:
committed by
MargeBot
parent
3b3282495d
commit
fdb6aa32f4
@@ -1310,6 +1310,7 @@ public final class me/proton/core/auth/presentation/entity/signup/SubscriptionDe
|
||||
}
|
||||
|
||||
public abstract interface class me/proton/core/auth/presentation/testing/ProtonTestEntryPoint {
|
||||
public abstract fun getFeatureFlagRepository ()Lme/proton/core/featureflag/domain/repository/FeatureFlagRepository;
|
||||
public abstract fun getGetAvailablePaymentProviders ()Lme/proton/core/payment/domain/usecase/GetAvailablePaymentProviders;
|
||||
public abstract fun getLoginTestHelper ()Lme/proton/core/auth/domain/testing/LoginTestHelper;
|
||||
}
|
||||
|
||||
+4
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Proton Technologies AG
|
||||
* This file is part of Proton Technologies AG and ProtonCore.
|
||||
* Copyright (c) 2023 Proton 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
|
||||
@@ -23,12 +23,14 @@ import dagger.hilt.EntryPoint
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import me.proton.core.auth.domain.testing.LoginTestHelper
|
||||
import me.proton.core.featureflag.domain.repository.FeatureFlagRepository
|
||||
import me.proton.core.payment.domain.usecase.GetAvailablePaymentProviders
|
||||
|
||||
@EntryPoint
|
||||
@InstallIn(SingletonComponent::class)
|
||||
@RestrictTo(RestrictTo.Scope.TESTS)
|
||||
interface ProtonTestEntryPoint {
|
||||
val featureFlagRepository: FeatureFlagRepository
|
||||
val getAvailablePaymentProviders: GetAvailablePaymentProviders
|
||||
val loginTestHelper: LoginTestHelper
|
||||
}
|
||||
|
||||
@@ -307,6 +307,7 @@ dependencies {
|
||||
androidTestImplementation(
|
||||
project(Module.androidInstrumentedTest),
|
||||
project(Module.paymentIapTest),
|
||||
project(Module.planTest),
|
||||
project(Module.quark),
|
||||
`android-test-runner`,
|
||||
`hilt-android-testing`,
|
||||
|
||||
+10
-3
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Proton Technologies AG
|
||||
* This file is part of Proton Technologies AG and ProtonCore.
|
||||
* Copyright (c) 2023 Proton 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
|
||||
@@ -26,6 +26,7 @@ import kotlinx.coroutines.runBlocking
|
||||
import me.proton.android.core.coreexample.Constants
|
||||
import me.proton.android.core.coreexample.MainActivity
|
||||
import me.proton.core.auth.presentation.testing.ProtonTestEntryPoint
|
||||
import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.payment.domain.usecase.PaymentProvider
|
||||
import me.proton.core.test.android.instrumented.ProtonTest
|
||||
import me.proton.core.test.android.instrumented.utils.Shell.setupDeviceForAutomation
|
||||
@@ -54,7 +55,8 @@ open class BaseTest(
|
||||
fun login(user: User) {
|
||||
Log.d(testTag, "Login user: ${user.name}")
|
||||
AddAccountRobot().back<CoreexampleRobot>().verify { accountSwitcherDisplayed() }
|
||||
authHelper.login(user.name, user.password)
|
||||
val sessionInfo = authHelper.login(user.name, user.password)
|
||||
fetchUnleashFeatureFlags(sessionInfo.userId)
|
||||
Log.d(testTag, "Login done.")
|
||||
}
|
||||
|
||||
@@ -79,6 +81,7 @@ open class BaseTest(
|
||||
fun prepare() {
|
||||
setupDeviceForAutomation(true)
|
||||
authHelper.logoutAll()
|
||||
fetchUnleashFeatureFlags(userId = null)
|
||||
Plan.Dev.text = Plan.MailPlus.text
|
||||
Plan.Dev.planName = Plan.MailPlus.planName
|
||||
}
|
||||
@@ -95,5 +98,9 @@ open class BaseTest(
|
||||
availablePaymentProviders().filter {
|
||||
it != PaymentProvider.PayPal
|
||||
}.toSet()
|
||||
|
||||
private fun fetchUnleashFeatureFlags(userId: UserId? = null) = runBlocking {
|
||||
protonTestEntryPoint.featureFlagRepository.getAll(userId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Proton 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.android.uitests.tests.medium.payments
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import me.proton.core.domain.entity.AppStore
|
||||
import me.proton.core.test.quark.data.Card
|
||||
import me.proton.core.test.quark.data.Plan
|
||||
import me.proton.core.test.android.robots.payments.ExistingPaymentMethodsRobot
|
||||
import me.proton.core.test.android.robots.payments.ExistingPaymentMethodsRobot.PaymentMethodElement.paymentMethod
|
||||
import me.proton.core.test.android.uitests.robot.CoreexampleRobot
|
||||
import me.proton.core.test.android.uitests.tests.BaseTest
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
import me.proton.core.payment.presentation.R
|
||||
import me.proton.core.plan.test.robot.SubscriptionRobot
|
||||
import me.proton.core.test.android.instrumented.utils.StringUtils.stringFromResource
|
||||
|
||||
@RunWith(Parameterized::class)
|
||||
class DynamicExistingPaymentMethodTests(
|
||||
private val appStore: AppStore,
|
||||
private val card: Boolean,
|
||||
private val paypal: Boolean,
|
||||
private val inApp: Boolean
|
||||
) : BaseTest() {
|
||||
|
||||
@Before
|
||||
fun setPaymentMethods() {
|
||||
quark.setPaymentMethods(appStore, card, paypal, inApp)
|
||||
}
|
||||
|
||||
@After
|
||||
fun setDefaults() {
|
||||
quark.setDefaultPaymentMethods()
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Requires user with paypal account linked")
|
||||
fun existingPaypalMethodDisplayed() {
|
||||
login(userWithPaypal)
|
||||
|
||||
CoreexampleRobot().plansUpgrade()
|
||||
SubscriptionRobot.selectPlan(Plan.Dev)
|
||||
ExistingPaymentMethodsRobot().verify {
|
||||
paymentMethodDisplayed("PayPal", userWithPaypal.paypal)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun existingCreditCardMethodDisplayed() {
|
||||
login(userWithCard)
|
||||
|
||||
CoreexampleRobot().plansUpgrade()
|
||||
SubscriptionRobot.selectPlan(Plan.Dev)
|
||||
ExistingPaymentMethodsRobot().verify {
|
||||
paymentMethodDisplayed(Card.default.details(), Card.default.name)
|
||||
if (inApp) {
|
||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
googlePaymentMethodDisplayed("${context.getString(R.string.payments_method_google)}*")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Requires user with paypal account linked")
|
||||
fun existingCreditCardAndPayPalDisplayed() {
|
||||
val user = users.getUser { it.paypal.isNotEmpty() && it.cards.isNotEmpty() && !it.isPaid }
|
||||
val card = user.cards[0]
|
||||
|
||||
login(user)
|
||||
|
||||
CoreexampleRobot().plansUpgrade()
|
||||
SubscriptionRobot.selectPlan(Plan.Dev)
|
||||
ExistingPaymentMethodsRobot().verify {
|
||||
paymentMethodDisplayed(card.details(), card.name)
|
||||
paymentMethodDisplayed("PayPal", user.paypal)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Requires user with paypal account linked")
|
||||
fun switchPaymentMethod() {
|
||||
val user = users.getUser { it.paypal.isNotEmpty() && it.cards.isNotEmpty() && !it.isPaid }
|
||||
|
||||
CoreexampleRobot().plansUpgrade()
|
||||
SubscriptionRobot.selectPlan(Plan.Dev)
|
||||
ExistingPaymentMethodsRobot().verify {
|
||||
paymentMethod(user.paypal).checkIsNotChecked()
|
||||
paymentMethod(user.cards[0].details()).checkIsChecked()
|
||||
}
|
||||
|
||||
ExistingPaymentMethodsRobot()
|
||||
.selectPaymentMethod(user.paypal)
|
||||
.verify {
|
||||
paymentMethod(user.paypal).checkIsChecked()
|
||||
paymentMethod(user.cards[0].details()).checkIsNotChecked()
|
||||
}
|
||||
}
|
||||
|
||||
private fun Card.details(): String = stringFromResource(
|
||||
R.string.payment_cc_list_item,
|
||||
brand.value,
|
||||
number.takeLast(4),
|
||||
expMonth,
|
||||
expYear
|
||||
)
|
||||
|
||||
companion object {
|
||||
val userWithCard by lazy { quark.seedUserWithCreditCard() }
|
||||
val userWithPaypal by lazy { users.getUser { it.paypal.isNotEmpty() } }
|
||||
|
||||
@get:Parameterized.Parameters(name = "appStore_{0}_card_{1}_paypal_{2}_inApp_{3}")
|
||||
@get:JvmStatic
|
||||
val data = listOf(
|
||||
// appStore, card, paypal, inApp
|
||||
arrayOf(AppStore.GooglePlay, true, true, true),
|
||||
arrayOf(AppStore.GooglePlay, true, true, false),
|
||||
arrayOf(AppStore.GooglePlay, true, false, true),
|
||||
arrayOf(AppStore.GooglePlay, true, false, false)
|
||||
).toList()
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Proton 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.android.uitests.tests.medium.payments
|
||||
|
||||
import me.proton.core.domain.entity.AppStore
|
||||
import me.proton.core.payment.presentation.R
|
||||
import me.proton.core.plan.test.robot.SubscriptionRobot
|
||||
import me.proton.core.test.android.robots.payments.AddCreditCardRobot
|
||||
import me.proton.core.test.android.uitests.robot.CoreexampleRobot
|
||||
import me.proton.core.test.android.uitests.tests.BaseTest
|
||||
import me.proton.core.test.quark.data.Plan
|
||||
import me.proton.core.test.quark.data.User
|
||||
import org.junit.After
|
||||
import org.junit.Test
|
||||
|
||||
class DynamicNewCreditCardTests : BaseTest() {
|
||||
|
||||
private val newCreditCardRobot = AddCreditCardRobot()
|
||||
|
||||
@After
|
||||
fun setDefaults() {
|
||||
quark.setDefaultPaymentMethods()
|
||||
}
|
||||
|
||||
private fun goToPlanUpgrade() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = false)
|
||||
|
||||
login(userWithoutCard)
|
||||
|
||||
CoreexampleRobot().plansCurrent()
|
||||
SubscriptionRobot.selectPlan(Plan.Dev)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun backToPlanSelection() {
|
||||
goToPlanUpgrade()
|
||||
newCreditCardRobot.close<CoreexampleRobot>()
|
||||
SubscriptionRobot.verifyAtLeastOnePlanIsShown()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun missingPaymentDetails() {
|
||||
goToPlanUpgrade()
|
||||
newCreditCardRobot
|
||||
.pay<AddCreditCardRobot>()
|
||||
.verify {
|
||||
inputErrorDisplayed(R.string.payments_error_card_name, scroll = true)
|
||||
inputErrorDisplayed(R.string.payments_error_card_number, scroll = true)
|
||||
inputErrorDisplayed(R.string.payments_error_cvc, scroll = true)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun invalidCreditCardNumber() {
|
||||
goToPlanUpgrade()
|
||||
newCreditCardRobot
|
||||
.ccname("Test name")
|
||||
.country()
|
||||
.selectCountry<AddCreditCardRobot>("Angola")
|
||||
.expirationDate("1234")
|
||||
.cvc("123")
|
||||
.ccnumber("424242424242424")
|
||||
.postalCode("1234")
|
||||
.pay<AddCreditCardRobot>()
|
||||
.verify { errorSnackbarDisplayed("Your card has been declined") }
|
||||
}
|
||||
|
||||
companion object {
|
||||
val userWithoutCard: User = quark.userCreate().first
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Proton Technologies AG
|
||||
* This file is part of Proton Technologies AG and ProtonCore.
|
||||
* Copyright (c) 2023 Proton 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
|
||||
@@ -36,6 +36,7 @@ import org.junit.runners.Parameterized
|
||||
import me.proton.core.payment.presentation.R
|
||||
import me.proton.core.test.android.instrumented.utils.StringUtils.stringFromResource
|
||||
|
||||
@Ignore("Replaced with DynamicExistingPaymentMethodTests")
|
||||
@RunWith(Parameterized::class)
|
||||
class ExistingPaymentMethodTests(
|
||||
private val appStore: AppStore,
|
||||
|
||||
+4
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Proton Technologies AG
|
||||
* This file is part of Proton Technologies AG and ProtonCore.
|
||||
* Copyright (c) 2023 Proton 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
|
||||
@@ -27,8 +27,10 @@ import me.proton.core.test.android.robots.plans.SelectPlanRobot
|
||||
import me.proton.core.test.android.uitests.robot.CoreexampleRobot
|
||||
import me.proton.core.test.android.uitests.tests.BaseTest
|
||||
import org.junit.After
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
|
||||
@Ignore("Replaced by DynamicNewCreditCardTests")
|
||||
class NewCreditCardTests : BaseTest() {
|
||||
|
||||
private val newCreditCardRobot = AddCreditCardRobot()
|
||||
|
||||
+2
@@ -31,11 +31,13 @@ import me.proton.core.test.android.uitests.robot.CoreexampleRobot
|
||||
import me.proton.core.test.android.uitests.tests.BaseTest
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import java.text.DateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
|
||||
@Ignore("Replaced by CurrentDynamicPlanTests")
|
||||
class CurrentPlanTests : BaseTest() {
|
||||
private fun navigateUserToCurrentPlans(user: User): SelectPlanRobot {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = false)
|
||||
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Proton 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.android.uitests.tests.medium.plans
|
||||
|
||||
import android.content.Context
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import me.proton.core.domain.entity.AppStore
|
||||
import me.proton.core.plan.presentation.R
|
||||
import me.proton.core.plan.presentation.entity.PlanCycle
|
||||
import me.proton.core.plan.test.robot.SubscriptionRobot
|
||||
import me.proton.core.test.android.uitests.robot.CoreexampleRobot
|
||||
import me.proton.core.test.android.uitests.tests.BaseTest
|
||||
import me.proton.core.test.quark.data.Plan
|
||||
import me.proton.core.test.quark.data.User
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import java.text.DateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
|
||||
class DynamicCurrentPlanTests : BaseTest() {
|
||||
private fun navigateUserToCurrentPlans(user: User) {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = false)
|
||||
login(user)
|
||||
|
||||
CoreexampleRobot().plansCurrent()
|
||||
}
|
||||
|
||||
@Before
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
quark.jailUnban()
|
||||
}
|
||||
|
||||
@After
|
||||
fun setDefaults() {
|
||||
quark.setDefaultPaymentMethods()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun userWithFreePlan() {
|
||||
val user = quark.userCreate().first
|
||||
navigateUserToCurrentPlans(user)
|
||||
SubscriptionRobot.apply {
|
||||
verifySubscriptionIsShown()
|
||||
verifyUpgradeYourPlanTextIsDisplayed()
|
||||
verifyAtLeastOnePlanIsShown()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun userWithPaidPlan() {
|
||||
val paidUser = User(plan = Plan.Unlimited)
|
||||
quark.seedNewSubscriberWithCycle(paidUser, PlanCycle.YEARLY.cycleDurationMonths)
|
||||
navigateUserToCurrentPlans(paidUser)
|
||||
SubscriptionRobot.apply {
|
||||
verifySubscriptionIsShown()
|
||||
verifyCannotManagePlansFromMobile()
|
||||
verifyNoPaidPlansAreShown()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun userWithPaidPlanCardAndIAPPayment1month() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = true)
|
||||
val paidUserCycle1 = User(plan = Plan.MailPlus)
|
||||
val cycle1 = PlanCycle.OTHER.apply {
|
||||
cycleDurationMonths = 1
|
||||
}
|
||||
val user = quark.seedNewSubscriberWithCycle(paidUserCycle1, cycle1.cycleDurationMonths)
|
||||
login(user)
|
||||
|
||||
CoreexampleRobot().plansCurrent()
|
||||
SubscriptionRobot.apply {
|
||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
val cycleText = context.resources.getQuantityString(
|
||||
R.plurals.plans_billing_other_period,
|
||||
cycle1.cycleDurationMonths,
|
||||
cycle1.cycleDurationMonths
|
||||
)
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.timeInMillis = System.currentTimeMillis()
|
||||
calendar.add(Calendar.MONTH, 1)
|
||||
|
||||
verifyPlanRenewalDisplayed(context.calendarToDateFormat(calendar.time).toString())
|
||||
verifyPlanCycleDisplayed(cycleText)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun userWithPaidPlanCardAndIAPPayment12months() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = true)
|
||||
val paidUserCycle12 = User(plan = Plan.MailPlus)
|
||||
val cycle12 = PlanCycle.OTHER.apply {
|
||||
cycleDurationMonths = 12
|
||||
}
|
||||
val user = quark.seedNewSubscriberWithCycle(paidUserCycle12, cycle12.cycleDurationMonths)
|
||||
login(user)
|
||||
|
||||
CoreexampleRobot().plansCurrent()
|
||||
SubscriptionRobot.apply {
|
||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.timeInMillis = System.currentTimeMillis()
|
||||
calendar.add(Calendar.YEAR, 1)
|
||||
|
||||
verifyPlanRenewalDisplayed(context.calendarToDateFormat(calendar.time).toString())
|
||||
verifyPlanCycleDisplayed(context.getString(R.string.plans_billing_yearly))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun userWithPaidPlanCardAndIAPPayment15months() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = true)
|
||||
val paidUserCycle15 = User(plan = Plan.VpnPlus)
|
||||
val cycle15 = PlanCycle.OTHER.apply {
|
||||
cycleDurationMonths = 15
|
||||
}
|
||||
val user = quark.seedNewSubscriberWithCycle(paidUserCycle15, cycle15.cycleDurationMonths)
|
||||
login(user)
|
||||
|
||||
CoreexampleRobot().plansCurrent()
|
||||
SubscriptionRobot.apply {
|
||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
val cycleText = context.resources.getQuantityString(
|
||||
R.plurals.plans_billing_other_period,
|
||||
cycle15.cycleDurationMonths,
|
||||
cycle15.cycleDurationMonths
|
||||
)
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.timeInMillis = System.currentTimeMillis()
|
||||
calendar.add(Calendar.MONTH, 15)
|
||||
|
||||
verifyPlanRenewalDisplayed(context.calendarToDateFormat(calendar.time).toString())
|
||||
verifyPlanCycleDisplayed(cycleText)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun userWithPaidPlanCardAndIAPPayment30months() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = true)
|
||||
val paidUserCycle30 = User(plan = Plan.VpnPlus)
|
||||
val cycle30 = PlanCycle.OTHER.apply {
|
||||
cycleDurationMonths = 30
|
||||
}
|
||||
val user = quark.seedNewSubscriberWithCycle(paidUserCycle30, cycle30.cycleDurationMonths)
|
||||
login(user)
|
||||
|
||||
CoreexampleRobot().plansCurrent()
|
||||
SubscriptionRobot.apply {
|
||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
val cycleText = context.resources.getQuantityString(
|
||||
R.plurals.plans_billing_other_period,
|
||||
cycle30.cycleDurationMonths,
|
||||
cycle30.cycleDurationMonths
|
||||
)
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.timeInMillis = System.currentTimeMillis()
|
||||
calendar.add(Calendar.MONTH, 30)
|
||||
|
||||
verifyPlanRenewalDisplayed(context.calendarToDateFormat(calendar.time).toString())
|
||||
verifyPlanCycleDisplayed(cycleText)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Context.calendarToDateFormat(date: Date) = HtmlCompat.fromHtml(
|
||||
String.format(
|
||||
getString(R.string.plans_renewal_date),
|
||||
DateFormat.getDateInstance().format(date)
|
||||
),
|
||||
HtmlCompat.FROM_HTML_MODE_LEGACY
|
||||
)
|
||||
}
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Proton 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.android.uitests.tests.medium.plans
|
||||
|
||||
import me.proton.core.domain.entity.AppStore
|
||||
import me.proton.core.paymentiap.test.robot.GoogleIAPRobot
|
||||
import me.proton.core.plan.test.robot.SubscriptionRobot
|
||||
import me.proton.core.test.android.robots.CoreRobot
|
||||
import me.proton.core.test.android.robots.auth.AddAccountRobot
|
||||
import me.proton.core.test.android.robots.auth.signup.ChooseUsernameRobot
|
||||
import me.proton.core.test.android.robots.auth.signup.RecoveryMethodsRobot
|
||||
import me.proton.core.test.android.robots.humanverification.HVRobot
|
||||
import me.proton.core.test.android.robots.payments.AddCreditCardRobot
|
||||
import me.proton.core.test.android.uitests.tests.BaseTest
|
||||
import me.proton.core.test.android.uitests.tests.SmokeTest
|
||||
import me.proton.core.test.quark.data.Plan.Dev
|
||||
import me.proton.core.test.quark.data.Plan.Free
|
||||
import me.proton.core.test.quark.data.User
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
class DynamicSelectPlanTests : BaseTest() {
|
||||
@After
|
||||
fun setDefaults() {
|
||||
quark.setDefaultPaymentMethods()
|
||||
}
|
||||
|
||||
@Before
|
||||
fun goToPlanSelection() {
|
||||
quark.jailUnban()
|
||||
|
||||
AddAccountRobot()
|
||||
.createAccount()
|
||||
.chooseInternalEmail()
|
||||
.verify { domainInputDisplayed() }
|
||||
|
||||
val user = User()
|
||||
ChooseUsernameRobot()
|
||||
.username(user.name)
|
||||
.next()
|
||||
.setAndConfirmPassword<RecoveryMethodsRobot>(user.password)
|
||||
.skip()
|
||||
.skipConfirm<CoreRobot>()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyInitialState() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = false)
|
||||
|
||||
SubscriptionRobot.verifyAtLeastOnePlanIsShown()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun selectFreeAndCancelHumanVerification() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = false)
|
||||
|
||||
SubscriptionRobot.selectPlan(Free)
|
||||
HVRobot().apply {
|
||||
verify { hvElementsDisplayed() }
|
||||
}.close<CoreRobot>()
|
||||
SubscriptionRobot.verifyAtLeastOnePlanIsShown()
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmokeTest
|
||||
fun selectPlusAndCancelPayment() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = false)
|
||||
|
||||
SubscriptionRobot.selectPlan(Dev)
|
||||
AddCreditCardRobot()
|
||||
.apply {
|
||||
verify<AddCreditCardRobot.Verify> {
|
||||
nextPaymentProviderButtonNotDisplayed()
|
||||
addCreditCardElementsDisplayed()
|
||||
}
|
||||
}
|
||||
.close<CoreRobot>()
|
||||
SubscriptionRobot.verifyAtLeastOnePlanIsShown()
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmokeTest
|
||||
fun selectPlusAndCancelPaymentIAPOnly() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = false, paypal = false, inApp = true)
|
||||
|
||||
SubscriptionRobot.selectPlan(Dev)
|
||||
GoogleIAPRobot()
|
||||
.apply {
|
||||
verify<GoogleIAPRobot.Verify> {
|
||||
googleIAPElementsDisplayed()
|
||||
nextPaymentProviderButtonIsNotVisible()
|
||||
}
|
||||
}
|
||||
.close<CoreRobot>()
|
||||
SubscriptionRobot.verifyAtLeastOnePlanIsShown()
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmokeTest
|
||||
fun selectPlusAndCancelPaymentIAPAndCard() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = true)
|
||||
|
||||
SubscriptionRobot.selectPlan(Dev)
|
||||
AddCreditCardRobot()
|
||||
.apply {
|
||||
verify<AddCreditCardRobot.Verify> { nextPaymentProviderButtonDisplayed() }
|
||||
}
|
||||
.switchPaymentProvider<GoogleIAPRobot>()
|
||||
GoogleIAPRobot()
|
||||
.apply {
|
||||
verify<GoogleIAPRobot.Verify> { googleIAPElementsDisplayed() }
|
||||
}
|
||||
.close<CoreRobot>()
|
||||
SubscriptionRobot.verifyAtLeastOnePlanIsShown()
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmokeTest
|
||||
fun selectPlusNoPaymentProvidersAvailable() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = false, paypal = false, inApp = false)
|
||||
SubscriptionRobot.selectPlan(Dev)
|
||||
SubscriptionRobot.verifyAtLeastOnePlanIsShown()
|
||||
}
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Proton 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.android.uitests.tests.medium.plans
|
||||
|
||||
import me.proton.core.domain.entity.AppStore
|
||||
import me.proton.core.plan.presentation.entity.PlanCycle
|
||||
import me.proton.core.plan.test.robot.SubscriptionRobot
|
||||
import me.proton.core.test.android.uitests.robot.CoreexampleRobot
|
||||
import me.proton.core.test.android.uitests.tests.BaseTest
|
||||
import me.proton.core.test.android.uitests.tests.SmokeTest
|
||||
import me.proton.core.test.quark.data.Plan
|
||||
import me.proton.core.test.quark.data.User
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
class DynamicUpgradePlanTests : BaseTest() {
|
||||
private val coreExampleRobot = CoreexampleRobot()
|
||||
|
||||
@Before
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
quark.jailUnban()
|
||||
}
|
||||
|
||||
@After
|
||||
fun setDefaults() {
|
||||
quark.setDefaultPaymentMethods()
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmokeTest
|
||||
fun userWithFreePlan() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = false)
|
||||
val freeUser = quark.userCreate().first
|
||||
login(freeUser)
|
||||
|
||||
coreExampleRobot.plansUpgrade()
|
||||
SubscriptionRobot.apply {
|
||||
togglePlan(Plan.Dev)
|
||||
verifyCanGetPlan(Plan.Dev)
|
||||
close()
|
||||
}
|
||||
|
||||
coreExampleRobot.verify { accountSwitcherDisplayed() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun userWithPaidPlanCardPayment() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = false)
|
||||
val paidUser = User(plan = Plan.Unlimited)
|
||||
quark.seedNewSubscriberWithCycle(paidUser, PlanCycle.YEARLY.cycleDurationMonths)
|
||||
login(paidUser)
|
||||
|
||||
coreExampleRobot.plansUpgrade()
|
||||
SubscriptionRobot.verifyNoUpgradeAvailable()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun userWithPaidPlanCardAndIAPPayment1month() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = true)
|
||||
val paidUserCycle1 = User(plan = Plan.MailPlus)
|
||||
val cycle1 = PlanCycle.OTHER.apply {
|
||||
cycleDurationMonths = 1
|
||||
}
|
||||
val user = quark.seedNewSubscriberWithCycle(paidUserCycle1, cycle1.cycleDurationMonths)
|
||||
login(user)
|
||||
|
||||
coreExampleRobot.plansUpgrade()
|
||||
SubscriptionRobot.apply {
|
||||
verifyNoPaidPlansAreShown()
|
||||
verifyNoUpgradeAvailable()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun userWithPaidPlanCardAndIAPPayment12months() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = true)
|
||||
val paidUserCycle12 = User(plan = Plan.MailPlus)
|
||||
val cycle12 = PlanCycle.OTHER.apply {
|
||||
cycleDurationMonths = 12
|
||||
}
|
||||
val user = quark.seedNewSubscriberWithCycle(paidUserCycle12, cycle12.cycleDurationMonths)
|
||||
login(user)
|
||||
|
||||
coreExampleRobot.plansUpgrade()
|
||||
SubscriptionRobot.apply {
|
||||
verifyNoPaidPlansAreShown()
|
||||
verifyNoUpgradeAvailable()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun userWithPaidPlanCardAndIAPPayment15months() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = true)
|
||||
val paidUserCycle15 = User(plan = Plan.VpnPlus)
|
||||
val cycle15 = PlanCycle.OTHER.apply {
|
||||
cycleDurationMonths = 15
|
||||
}
|
||||
val user = quark.seedNewSubscriberWithCycle(paidUserCycle15, cycle15.cycleDurationMonths)
|
||||
login(user)
|
||||
|
||||
coreExampleRobot.plansUpgrade()
|
||||
SubscriptionRobot.apply {
|
||||
verifyNoPaidPlansAreShown()
|
||||
verifyNoUpgradeAvailable()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun userWithPaidPlanCardAndIAPPayment30months() {
|
||||
quark.setPaymentMethods(AppStore.GooglePlay, card = true, paypal = false, inApp = true)
|
||||
val paidUserCycle15 = User(plan = Plan.VpnPlus)
|
||||
val cycle15 = PlanCycle.OTHER.apply {
|
||||
cycleDurationMonths = 30
|
||||
}
|
||||
val user = quark.seedNewSubscriberWithCycle(paidUserCycle15, cycle15.cycleDurationMonths)
|
||||
login(user)
|
||||
|
||||
coreExampleRobot.plansUpgrade()
|
||||
SubscriptionRobot.apply {
|
||||
verifyNoPaidPlansAreShown()
|
||||
verifyNoUpgradeAvailable()
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Proton Technologies AG
|
||||
* This file is part of Proton Technologies AG and ProtonCore.
|
||||
* Copyright (c) 2023 Proton 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
|
||||
@@ -30,8 +30,10 @@ import me.proton.core.test.android.robots.plans.SelectPlanRobot
|
||||
import me.proton.core.test.android.uitests.tests.BaseTest
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
|
||||
@Ignore("Replaced with SelectDynamicPlanTests")
|
||||
class SelectPlanForIAPTests : BaseTest() {
|
||||
|
||||
private var humanVerificationRobot: HVRobot? = null
|
||||
|
||||
+4
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Proton Technologies AG
|
||||
* This file is part of Proton Technologies AG and ProtonCore.
|
||||
* Copyright (c) 2023 Proton 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
|
||||
@@ -33,8 +33,10 @@ import me.proton.core.test.android.uitests.tests.BaseTest
|
||||
import me.proton.core.test.android.uitests.tests.SmokeTest
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
|
||||
@Ignore("Replaced with SelectDynamicPlanTests")
|
||||
class SelectPlanTests : BaseTest() {
|
||||
|
||||
private var humanVerificationRobot: HVRobot? = null
|
||||
|
||||
+2
@@ -28,8 +28,10 @@ import me.proton.core.test.android.uitests.tests.BaseTest
|
||||
import me.proton.core.test.android.uitests.tests.SmokeTest
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
|
||||
@Ignore("Replaced with DynamicUpgradePlanTests")
|
||||
class UpgradePlanTests : BaseTest() {
|
||||
|
||||
private val selectPlanRobot = SelectPlanRobot()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"Plans": {
|
||||
"Type": 1,
|
||||
"Name": "free",
|
||||
"Title": "Proton Free",
|
||||
"Title": "Free",
|
||||
"MaxDomains": 0,
|
||||
"MaxAddresses": 1,
|
||||
"MaxCalendars": 1,
|
||||
|
||||
@@ -23,6 +23,7 @@ import androidx.startup.AppInitializer
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import me.proton.android.core.coreexample.init.AccountStateHandlerInitializer
|
||||
import me.proton.android.core.coreexample.init.EventManagerInitializer
|
||||
import me.proton.android.core.coreexample.init.FeatureFlagInitializer
|
||||
import me.proton.android.core.coreexample.init.LoggerInitializer
|
||||
import me.proton.core.keytransparency.presentation.init.KeyTransparencyInitializer
|
||||
import me.proton.android.core.coreexample.init.WorkManagerInitializer
|
||||
@@ -47,6 +48,7 @@ class CoreExampleApp : Application() {
|
||||
initializeComponent(UnAuthSessionFetcherInitializer::class.java)
|
||||
initializeComponent(KeyTransparencyInitializer::class.java)
|
||||
initializeComponent(LoggerInitializer::class.java)
|
||||
initializeComponent(FeatureFlagInitializer::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Proton 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.android.core.coreexample.init
|
||||
|
||||
import android.content.Context
|
||||
import androidx.startup.Initializer
|
||||
import dagger.hilt.EntryPoint
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.EntryPointAccessors
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import me.proton.core.featureflag.data.FeatureFlagRefreshStarter
|
||||
|
||||
class FeatureFlagInitializer: Initializer<Unit> {
|
||||
override fun create(context: Context) {
|
||||
EntryPointAccessors.fromApplication(
|
||||
context.applicationContext,
|
||||
FeatureFlagInitializerEntryPoint::class.java
|
||||
).featureFlagRefreshStarter().start()
|
||||
}
|
||||
|
||||
override fun dependencies(): List<Class<out Initializer<*>?>> = listOf(
|
||||
WorkManagerInitializer::class.java
|
||||
)
|
||||
|
||||
@EntryPoint
|
||||
@InstallIn(SingletonComponent::class)
|
||||
interface FeatureFlagInitializerEntryPoint {
|
||||
fun featureFlagRefreshStarter(): FeatureFlagRefreshStarter
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2020 Proton Technologies AG
|
||||
~ This file is part of Proton Technologies AG and ProtonCore.
|
||||
~ Copyright (c) 2023 Proton 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
|
||||
@@ -51,9 +51,11 @@
|
||||
android:layout_marginStart="@dimen/default_gap"
|
||||
android:layout_marginEnd="@dimen/default_gap"
|
||||
android:layout_marginBottom="@dimen/gap_medium"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<me.proton.core.presentation.ui.view.ProtonProgressButton
|
||||
android:id="@+id/payButton"
|
||||
|
||||
@@ -40,9 +40,17 @@ public final class me/proton/core/plan/test/MinimalUpgradeTests$DefaultImpls {
|
||||
|
||||
public final class me/proton/core/plan/test/robot/SubscriptionRobot {
|
||||
public static final field INSTANCE Lme/proton/core/plan/test/robot/SubscriptionRobot;
|
||||
public final fun close ()V
|
||||
public final fun selectPlan (Lme/proton/core/test/quark/data/Plan;)V
|
||||
public final fun togglePlan (Lme/proton/core/test/quark/data/Plan;)V
|
||||
public final fun verifyAtLeastOnePlanIsShown ()V
|
||||
public final fun verifyCanGetPlan (Lme/proton/core/test/quark/data/Plan;)V
|
||||
public final fun verifyCannotManagePlansFromMobile ()V
|
||||
public final fun verifyCannotUpgradeFromMobile ()V
|
||||
public final fun verifyNoPaidPlansAreShown ()V
|
||||
public final fun verifyNoUpgradeAvailable ()V
|
||||
public final fun verifyPlanCycleDisplayed (Ljava/lang/String;)V
|
||||
public final fun verifyPlanRenewalDisplayed (Ljava/lang/String;)V
|
||||
public final fun verifySubscriptionIsShown ()V
|
||||
public final fun verifyUpgradeIsShown ()V
|
||||
public final fun verifyUpgradeYourPlanTextIsDisplayed ()V
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Proton Technologies AG
|
||||
* Copyright (c) 2023 Proton AG
|
||||
* This file is part of Proton AG and ProtonCore.
|
||||
*
|
||||
* ProtonCore is free software: you can redistribute it and/or modify
|
||||
@@ -19,7 +19,7 @@
|
||||
package me.proton.core.plan.test
|
||||
|
||||
import me.proton.core.plan.test.robot.SubscriptionRobot.verifyAtLeastOnePlanIsShown
|
||||
import me.proton.core.plan.test.robot.SubscriptionRobot.verifyCannotUpgradeFromMobile
|
||||
import me.proton.core.plan.test.robot.SubscriptionRobot.verifyCannotManagePlansFromMobile
|
||||
import me.proton.core.plan.test.robot.SubscriptionRobot.verifyNoPaidPlansAreShown
|
||||
import me.proton.core.plan.test.robot.SubscriptionRobot.verifySubscriptionIsShown
|
||||
import me.proton.core.plan.test.robot.SubscriptionRobot.verifyUpgradeYourPlanTextIsDisplayed
|
||||
@@ -69,6 +69,6 @@ public interface MinimalSubscriptionTests {
|
||||
quark.setPaymentMethods(card = false, paypal = false, inApp = false)
|
||||
startSubscription(users.getUser { it.isPaid })
|
||||
verifySubscriptionIsShown()
|
||||
verifyCannotUpgradeFromMobile()
|
||||
verifyCannotManagePlansFromMobile()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Proton Technologies AG
|
||||
* Copyright (c) 2023 Proton AG
|
||||
* This file is part of Proton AG and ProtonCore.
|
||||
*
|
||||
* ProtonCore is free software: you can redistribute it and/or modify
|
||||
@@ -20,19 +20,32 @@ package me.proton.core.plan.test.robot
|
||||
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import me.proton.core.plan.presentation.R
|
||||
import me.proton.core.test.quark.data.Plan
|
||||
import me.proton.test.fusion.Fusion.device
|
||||
import me.proton.test.fusion.Fusion.view
|
||||
import me.proton.test.fusion.FusionConfig
|
||||
import me.proton.test.fusion.ui.espresso.builders.OnView
|
||||
|
||||
public object SubscriptionRobot {
|
||||
|
||||
private val toolbar = view.withId(R.id.toolbar)
|
||||
private val currentPlan = view.withId(R.id.subscription)
|
||||
private val planSelection = view.withId(R.id.plan_selection)
|
||||
private val upgradeYourPlanText = view.withText(R.string.plans_upgrade_your_plan)
|
||||
.withClassName("TextView")
|
||||
private val planSelectionWithCardView =
|
||||
view.withId(R.id.plan_selection).hasDescendant(view.withId(R.id.card_view))
|
||||
private val upgradeYourPlanText =
|
||||
view.withId(R.id.title).withText(R.string.plans_upgrade_your_plan)
|
||||
private val upgradeYourPlanTitle = view.withText(R.string.plans_upgrade_your_plan)
|
||||
.hasAncestor(toolbar)
|
||||
private val cannotUpgrade = view.withText(R.string.plans_can_not_upgrade_from_mobile)
|
||||
private val cardView = view.withId(R.id.card_view)
|
||||
private val managementInfo = view.withId(R.id.management_info)
|
||||
private val noUpgradeAvailableTextView = view.withText(R.string.plans_no_upgrade_available)
|
||||
|
||||
// region Actions
|
||||
|
||||
public fun close() {
|
||||
device.pressBack()
|
||||
}
|
||||
|
||||
private fun currentPlanIsDisplayed() {
|
||||
currentPlan.await { checkIsDisplayed() }
|
||||
@@ -53,14 +66,44 @@ public object SubscriptionRobot {
|
||||
private fun planSelectionIsDisplayed() {
|
||||
planSelection.scrollTo()
|
||||
planSelection.await { checkIsDisplayed() }
|
||||
planSelection.hasDescendant(cardView).checkIsDisplayed()
|
||||
planSelectionWithCardView.await { checkIsDisplayed() }
|
||||
}
|
||||
|
||||
private fun expandAndSelectFirstPlan() {
|
||||
planSelection.hasDescendant(cardView).click()
|
||||
planSelectionWithCardView.click()
|
||||
view.withCustomMatcher(ViewMatchers.withSubstring("Get"))
|
||||
}
|
||||
|
||||
private fun togglePlanItem(plan: Plan) {
|
||||
view.withId(R.id.title).containsText(plan.text).scrollTo().click()
|
||||
}
|
||||
|
||||
private fun getPlanButton(plan: Plan): OnView {
|
||||
val buttonText = FusionConfig.targetContext.getString(R.string.plans_get_proton, plan.text)
|
||||
return view.withId(R.id.content_button).containsText(buttonText)
|
||||
}
|
||||
|
||||
private fun expandAndSelectPlan(plan: Plan) {
|
||||
togglePlanItem(plan)
|
||||
|
||||
getPlanButton(plan)
|
||||
.scrollTo()
|
||||
.click()
|
||||
}
|
||||
|
||||
public fun selectPlan(plan: Plan) {
|
||||
planSelectionIsDisplayed()
|
||||
expandAndSelectPlan(plan)
|
||||
}
|
||||
|
||||
public fun togglePlan(plan: Plan) {
|
||||
togglePlanItem(plan)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Verifications
|
||||
|
||||
public fun verifySubscriptionIsShown() {
|
||||
currentPlanIsDisplayed()
|
||||
}
|
||||
@@ -89,4 +132,29 @@ public object SubscriptionRobot {
|
||||
public fun verifyCannotUpgradeFromMobile() {
|
||||
cannotUpgrade.checkIsDisplayed()
|
||||
}
|
||||
|
||||
public fun verifyNoUpgradeAvailable() {
|
||||
noUpgradeAvailableTextView.await { checkIsDisplayed() }
|
||||
}
|
||||
|
||||
public fun verifyCannotManagePlansFromMobile() {
|
||||
managementInfo.checkContainsText(R.string.plans_manage_your_subscription_other)
|
||||
}
|
||||
|
||||
public fun verifyPlanRenewalDisplayed(value: String) {
|
||||
view.withId(R.id.content_renewal).withText(value).await { checkIsDisplayed() }
|
||||
}
|
||||
|
||||
public fun verifyPlanCycleDisplayed(value: String) {
|
||||
view.withId(R.id.price_cycle).withText(value).await { checkIsDisplayed() }
|
||||
}
|
||||
|
||||
public fun verifyCanGetPlan(plan: Plan) {
|
||||
getPlanButton(plan)
|
||||
.scrollTo()
|
||||
.checkIsDisplayed()
|
||||
.checkIsEnabled()
|
||||
}
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
||||
@@ -216,6 +216,7 @@ public object Module {
|
||||
public const val planDomain: String = "$plan:plan-domain"
|
||||
public const val planData: String = "$plan:plan-data"
|
||||
public const val planPresentation: String = "$plan:plan-presentation"
|
||||
public const val planTest: String = "$plan:plan-test"
|
||||
|
||||
public const val push: String = ":push"
|
||||
public const val pushDomain: String = "$push:push-domain"
|
||||
|
||||
+3
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Proton Technologies AG
|
||||
* This file is part of Proton Technologies AG and ProtonCore.
|
||||
* Copyright (c) 2023 Proton 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
|
||||
@@ -28,6 +28,7 @@ import me.proton.core.test.quark.data.Plan
|
||||
import me.proton.core.test.android.robots.CoreRobot
|
||||
import me.proton.core.test.android.robots.CoreVerify
|
||||
|
||||
@Deprecated("Does not work with dynamic plans.")
|
||||
class SelectPlanRobot : CoreRobot() {
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Proton Technologies AG
|
||||
* Copyright (c) 2023 Proton AG
|
||||
* This file is part of Proton AG and ProtonCore.
|
||||
*
|
||||
* ProtonCore is free software: you can redistribute it and/or modify
|
||||
@@ -31,7 +31,7 @@ public enum class Plan(public var planName: String, public var text: String) {
|
||||
@Deprecated("This plan is no longer enabled.")
|
||||
Plus("plus", "ProtonMail Plus"),
|
||||
|
||||
Free("free", "Proton Free"),
|
||||
Free("free", "Free"),
|
||||
MailPlus("mail2022", "Mail Plus"),
|
||||
Unlimited("bundle2022", "Proton Unlimited"),
|
||||
VpnPlus("vpn2022", "VPN Plus"),
|
||||
|
||||
Reference in New Issue
Block a user