mirror of
https://github.com/ProtonMail/protoncore_android.git
synced 2026-06-14 09:54:49 +00:00
feat: Added test rules package.
This commit is contained in:
@@ -226,6 +226,7 @@ Core libraries coordinates can be found under [coordinates section](#coordinates
|
||||
| me.proton.core:test-android-instrumented |
|
||||
| me.proton.core:test-kotlin |
|
||||
| me.proton.core:test-quark |
|
||||
| me.proton.core:test-rule |
|
||||
| me.proton.core:user |
|
||||
| me.proton.core:user-dagger |
|
||||
| me.proton.core:user-data |
|
||||
|
||||
@@ -35,11 +35,7 @@ protonCoverage {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(
|
||||
project(Module.networkData),
|
||||
datastore,
|
||||
datastorePreferences,
|
||||
)
|
||||
implementation(project(Module.networkData))
|
||||
|
||||
testImplementation(junit, mockk)
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ public object Module {
|
||||
public const val androidTest: String = "$test:test-android"
|
||||
public const val androidInstrumentedTest: String = "$androidTest:test-android-instrumented"
|
||||
public const val quark: String = "$test:test-quark"
|
||||
public const val testRule: String = "$test:test-rule"
|
||||
// endregion
|
||||
|
||||
// region Shared
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
## Proton Rule: Streamlined Test Setup for Android
|
||||
|
||||
**Proton Rule** is an Android Kotlin library designed to simplify and organize test setup in your Android tests, focusing on common use cases for activity and Compose UI testing.
|
||||
|
||||
**Key Features:**
|
||||
|
||||
* **Reduced Boilerplate:** Streamline common tasks like activity/Compose test setup, test data injection, and environment configuration.
|
||||
* **Improved Organization:** Centralize configuration for cleaner and more maintainable tests.
|
||||
* **Customization:** Define custom annotations and rules for specific test requirements.
|
||||
|
||||
**Basic Usage:**
|
||||
|
||||
The `protonRule` function provides a central entry point for common test setups:
|
||||
|
||||
```kotlin
|
||||
@HiltAndroidTest
|
||||
class TestClass {
|
||||
|
||||
private val testSubscriptionData = TestSubscriptionData(plan = Plan.Unlimited).annotationTestData
|
||||
|
||||
@get:Rule
|
||||
val rule: ProtonRule = protonRule(
|
||||
testSubscriptionData,
|
||||
envConfig = EnvironmentConfig(host = "proton.black"),
|
||||
userData = TestUserData(name = randomUsername()),
|
||||
loginBefore = true,
|
||||
logoutBefore = true,
|
||||
logoutAfter = true,
|
||||
activityRule = activityScenarioRule<MainActivity>(),
|
||||
setUp = { }
|
||||
)
|
||||
|
||||
@Test
|
||||
fun defaultExample() {
|
||||
// MainActivity is started with a seeded user with Unlimited plan logged in on 'proton.black' environment.
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnvironmentConfig(host = "proton.me")
|
||||
@TestUserData(name = "pro", password = "pro", shouldSeed = false)
|
||||
fun overrideExample() {
|
||||
// MainActivity is started with a user 'pro' logged in on 'proton.me' environment. User will not be seeded beforehand
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@TestSubscriptionData(plan = Plan.MailPlus)
|
||||
fun overrideExample2() {
|
||||
// MainActivity is started with a seeded user with MailPlus plan logged in on 'proton.black' environment.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**3. Helper Functions:**
|
||||
|
||||
* `protonActivityScenarioRule<A>()`: Sets up an `ActivityScenarioRule` for a specific activity type with optional setup logic.
|
||||
* `protonAndroidComposeRule<A>()`: Sets up a `ComposeTestRule` for a Compose activity with optional setup logic.
|
||||
|
||||
These functions are useful for most common case scenarios:
|
||||
```kotlin
|
||||
@HiltAndroidTest
|
||||
class TestClass {
|
||||
|
||||
// If using Views
|
||||
@get:Rule
|
||||
val protonRule: ProtonRule = protonActivityScenarioRule<MainActivity>(
|
||||
val customTestData = TestFeatureEnabled(false).annotationTestData
|
||||
) {
|
||||
MainInitializer.init(targetContext)
|
||||
}
|
||||
|
||||
// If using Compose
|
||||
@get:Rule
|
||||
val protonRule: ProtonRule = protonAndroidComposeRule<MainActivity>(
|
||||
val customTestData = TestFeatureEnabled(false).annotationTestData
|
||||
) {
|
||||
MainInitializer.init(targetContext)
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnvironmentConfig(host = "scientist.proton.black")
|
||||
fun example() {
|
||||
// MainActivity is started with following configuration:
|
||||
// 1. Default environment configuration provided by the application
|
||||
// 2. Hilt test dependencies injected
|
||||
// 3. Logged in with freshly created user with random username
|
||||
// Can be accessed by protonRule.testDataRule.testUserData
|
||||
// 4. All users are logged out before and after the test (to always assure clean state)
|
||||
// 5. Default environment configuration is overriden by annotation
|
||||
// 6. Test feature is disabled by default, but can be overriden by annotation @TestFeatureEnabled
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**4. Custom Annotations:**
|
||||
|
||||
Define custom annotations to capture test-specific configurations:
|
||||
|
||||
```kotlin
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
public annotation class TestFeatureEnabled(val enabled: Boolean = true)
|
||||
|
||||
public val TestFeatureEnabled.annotationTestData: AnnotationTestData<TestFeatureEnabled>
|
||||
get() = AnnotationTestData(
|
||||
this,
|
||||
implementation = { data ->
|
||||
// Enable/disable the feature based on data.enabled
|
||||
},
|
||||
tearDown = { _ ->
|
||||
// Reset feature state to default
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
**5. Using Annotations with Rules:**
|
||||
|
||||
Combine annotations and rules to tailor test setups:
|
||||
|
||||
```kotlin
|
||||
val customTestData = TestFeatureEnabled(false).annotationTestData, // Disable specific feature
|
||||
val otherTestData = OtherTestData().annotationTestData
|
||||
|
||||
@Rule
|
||||
override val protonRule: ProtonRule = protonActivityScenarioRule<MainActivity>(
|
||||
customData, otherTestData, // provided using 'vararg'
|
||||
logoutAfter = false
|
||||
)
|
||||
|
||||
@Test
|
||||
fun example() {
|
||||
assertFalse(customTestData.enabled)
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestFeatureEnabled(enabled = true)
|
||||
fun exampleOverride() {
|
||||
assertTrue(customTestData.enabled)
|
||||
}
|
||||
```
|
||||
|
||||
**Advanced Usage:**
|
||||
|
||||
For advanced setup you can use underlying test rules directly and/or combine them into your own rules:
|
||||
```kotlin
|
||||
class AdvancedTestSetup {
|
||||
private val testUserData = TestUserData(
|
||||
name = randomUsername(),
|
||||
password = "password",
|
||||
genKeys = TestUserData.GenKeys.RSA4096
|
||||
)
|
||||
|
||||
private val environmentConfig = EnvironmentConfig(host = "proton.black")
|
||||
|
||||
private val userConfig = ProtonRule.UserConfig(
|
||||
userData = testUserData,
|
||||
loginBefore = true,
|
||||
logoutBefore = true,
|
||||
logoutAfter = true
|
||||
)
|
||||
|
||||
private val testConfig = ProtonRule.TestConfig(
|
||||
envConfig = environmentConfig,
|
||||
annotationTestData = arrayOf(TestSubscriptionData(plan = Plan.Unlimited).annotationTestData),
|
||||
activityRule = activityScenarioRule<MainActivity>()
|
||||
)
|
||||
|
||||
@get:Rule
|
||||
val envConfigRule = EnvironmentConfigRule(
|
||||
defaultConfig = environmentConfig
|
||||
)
|
||||
|
||||
@get:Rule
|
||||
val hiltRule = HiltAndroidRule(this)
|
||||
|
||||
@get:Rule
|
||||
val testDataRule = QuarkTestDataRule(
|
||||
annotationTestData = testConfig.annotationTestData,
|
||||
initialTestUserData = userConfig.userData,
|
||||
environmentConfig = { envConfigRule.config }
|
||||
)
|
||||
|
||||
@get:Rule
|
||||
val authenticationRule: AuthenticationRule = AuthenticationRule(
|
||||
userConfig = userConfig
|
||||
)
|
||||
|
||||
@get:Rule
|
||||
val setupRule: ExternalResource = before {
|
||||
MainInitializer.init(targetContext)
|
||||
}
|
||||
|
||||
@get:Rule
|
||||
val activityRule = testConfig.activityRule
|
||||
|
||||
@Test
|
||||
@TestSubscriptionData(plan = Plan.Unlimited)
|
||||
fun example() {
|
||||
// Test will run under the same conditions as using protonActivityScenarioRule()
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,202 @@
|
||||
public class hilt_aggregated_deps/_me_proton_core_test_rule_di_TestEnvironmentConfigModule {
|
||||
public fun <init> ()V
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/AuthenticationRule : org/junit/rules/TestWatcher {
|
||||
public fun <init> (Lme/proton/core/test/rule/ProtonRule$UserConfig;)V
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/BuildConfig {
|
||||
public static final field BUILD_TYPE Ljava/lang/String;
|
||||
public static final field DEBUG Z
|
||||
public static final field LIBRARY_PACKAGE_NAME Ljava/lang/String;
|
||||
public fun <init> ()V
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/EnvironmentConfigRule : org/junit/rules/TestRule {
|
||||
public fun <init> ()V
|
||||
public fun <init> (Lme/proton/core/test/rule/annotation/EnvironmentConfig;)V
|
||||
public synthetic fun <init> (Lme/proton/core/test/rule/annotation/EnvironmentConfig;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public fun apply (Lorg/junit/runners/model/Statement;Lorg/junit/runner/Description;)Lorg/junit/runners/model/Statement;
|
||||
public final fun getConfig ()Lme/proton/core/test/rule/annotation/EnvironmentConfig;
|
||||
}
|
||||
|
||||
public class me/proton/core/test/rule/ProtonRule : org/junit/rules/TestRule {
|
||||
public fun <init> (Lme/proton/core/test/rule/ProtonRule$UserConfig;Lme/proton/core/test/rule/ProtonRule$TestConfig;Ljava/lang/Object;Lkotlin/jvm/functions/Function0;)V
|
||||
public fun apply (Lorg/junit/runners/model/Statement;Lorg/junit/runner/Description;)Lorg/junit/runners/model/Statement;
|
||||
public final fun getTestDataRule ()Lme/proton/core/test/rule/QuarkTestDataRule;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/ProtonRule$TestConfig {
|
||||
public fun <init> ()V
|
||||
public fun <init> (Lme/proton/core/test/rule/annotation/EnvironmentConfig;[Lme/proton/core/test/rule/annotation/AnnotationTestData;Lorg/junit/rules/TestRule;)V
|
||||
public synthetic fun <init> (Lme/proton/core/test/rule/annotation/EnvironmentConfig;[Lme/proton/core/test/rule/annotation/AnnotationTestData;Lorg/junit/rules/TestRule;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun component1 ()Lme/proton/core/test/rule/annotation/EnvironmentConfig;
|
||||
public final fun component2 ()[Lme/proton/core/test/rule/annotation/AnnotationTestData;
|
||||
public final fun component3 ()Lorg/junit/rules/TestRule;
|
||||
public final fun copy (Lme/proton/core/test/rule/annotation/EnvironmentConfig;[Lme/proton/core/test/rule/annotation/AnnotationTestData;Lorg/junit/rules/TestRule;)Lme/proton/core/test/rule/ProtonRule$TestConfig;
|
||||
public static synthetic fun copy$default (Lme/proton/core/test/rule/ProtonRule$TestConfig;Lme/proton/core/test/rule/annotation/EnvironmentConfig;[Lme/proton/core/test/rule/annotation/AnnotationTestData;Lorg/junit/rules/TestRule;ILjava/lang/Object;)Lme/proton/core/test/rule/ProtonRule$TestConfig;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getActivityRule ()Lorg/junit/rules/TestRule;
|
||||
public final fun getAnnotationTestData ()[Lme/proton/core/test/rule/annotation/AnnotationTestData;
|
||||
public final fun getEnvConfig ()Lme/proton/core/test/rule/annotation/EnvironmentConfig;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/ProtonRule$UserConfig {
|
||||
public fun <init> ()V
|
||||
public fun <init> (Lme/proton/core/test/rule/annotation/TestUserData;ZZZ)V
|
||||
public synthetic fun <init> (Lme/proton/core/test/rule/annotation/TestUserData;ZZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun component1 ()Lme/proton/core/test/rule/annotation/TestUserData;
|
||||
public final fun component2 ()Z
|
||||
public final fun component3 ()Z
|
||||
public final fun component4 ()Z
|
||||
public final fun copy (Lme/proton/core/test/rule/annotation/TestUserData;ZZZ)Lme/proton/core/test/rule/ProtonRule$UserConfig;
|
||||
public static synthetic fun copy$default (Lme/proton/core/test/rule/ProtonRule$UserConfig;Lme/proton/core/test/rule/annotation/TestUserData;ZZZILjava/lang/Object;)Lme/proton/core/test/rule/ProtonRule$UserConfig;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getLoginBefore ()Z
|
||||
public final fun getLogoutAfter ()Z
|
||||
public final fun getLogoutBefore ()Z
|
||||
public final fun getOverrideLogin ()Z
|
||||
public final fun getUserData ()Lme/proton/core/test/rule/annotation/TestUserData;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/ProtonRuleKt {
|
||||
public static final fun before (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Lorg/junit/rules/ExternalResource;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/QuarkTestDataRule : org/junit/rules/TestWatcher {
|
||||
public static final field Companion Lme/proton/core/test/rule/QuarkTestDataRule$Companion;
|
||||
public fun <init> ([Lme/proton/core/test/rule/annotation/AnnotationTestData;Lme/proton/core/test/rule/annotation/TestUserData;Lkotlin/jvm/functions/Function0;)V
|
||||
public final fun getTestData (Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
|
||||
public final fun getTestUserData ()Lme/proton/core/test/rule/annotation/TestUserData;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/QuarkTestDataRule$Companion {
|
||||
public final fun getQuarkClientTimeout ()Ljava/util/concurrent/atomic/AtomicReference;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/annotation/AnnotationTestData {
|
||||
public fun <init> (Ljava/lang/annotation/Annotation;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;)V
|
||||
public synthetic fun <init> (Ljava/lang/annotation/Annotation;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public fun <init> (Ljava/lang/annotation/Annotation;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;)V
|
||||
public synthetic fun <init> (Ljava/lang/annotation/Annotation;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public fun <init> (Ljava/lang/annotation/Annotation;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;)V
|
||||
public synthetic fun <init> (Ljava/lang/annotation/Annotation;Lkotlin/jvm/functions/Function4;Lkotlin/jvm/functions/Function4;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun getDefault ()Ljava/lang/annotation/Annotation;
|
||||
public final fun getImplementation ()Lkotlin/jvm/functions/Function4;
|
||||
public final fun getTearDown ()Lkotlin/jvm/functions/Function4;
|
||||
}
|
||||
|
||||
public abstract interface annotation class me/proton/core/test/rule/annotation/EnvironmentConfig : java/lang/annotation/Annotation {
|
||||
public static final field Companion Lme/proton/core/test/rule/annotation/EnvironmentConfig$Companion;
|
||||
public abstract fun host ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/annotation/EnvironmentConfig$Companion {
|
||||
public final fun fromConfiguration (Lme/proton/core/configuration/EnvironmentConfiguration;)Lme/proton/core/test/rule/annotation/EnvironmentConfig;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/annotation/EnvironmentConfigKt {
|
||||
public static final fun getConfigContractFieldsMap (Lme/proton/core/test/rule/annotation/EnvironmentConfig;)Ljava/util/Map;
|
||||
public static final fun toEnvironmentConfiguration (Lme/proton/core/test/rule/annotation/EnvironmentConfig;)Lme/proton/core/configuration/EnvironmentConfiguration;
|
||||
}
|
||||
|
||||
public abstract interface annotation class me/proton/core/test/rule/annotation/TestPaymentMethods : java/lang/annotation/Annotation {
|
||||
public abstract fun appStore ()Lme/proton/core/domain/entity/AppStore;
|
||||
public abstract fun card ()Z
|
||||
public abstract fun inApp ()Z
|
||||
public abstract fun paypal ()Z
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/annotation/TestPaymentMethodsKt {
|
||||
public static final fun getAnnotationTestData (Lme/proton/core/test/rule/annotation/TestPaymentMethods;)Lme/proton/core/test/rule/annotation/AnnotationTestData;
|
||||
}
|
||||
|
||||
public abstract interface annotation class me/proton/core/test/rule/annotation/TestSubscriptionData : java/lang/annotation/Annotation {
|
||||
public abstract fun couponCode ()Ljava/lang/String;
|
||||
public abstract fun delinquent ()Z
|
||||
public abstract fun plan ()Lme/proton/core/test/quark/data/Plan;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/annotation/TestSubscriptionDataKt {
|
||||
public static final fun getAnnotationTestData (Lme/proton/core/test/rule/annotation/TestSubscriptionData;)Lme/proton/core/test/rule/annotation/AnnotationTestData;
|
||||
}
|
||||
|
||||
public abstract interface annotation class me/proton/core/test/rule/annotation/TestUserData : java/lang/annotation/Annotation {
|
||||
public static final field Companion Lme/proton/core/test/rule/annotation/TestUserData$Companion;
|
||||
public abstract fun authVersion ()I
|
||||
public abstract fun createAddress ()Z
|
||||
public abstract fun external ()Z
|
||||
public abstract fun externalEmail ()Ljava/lang/String;
|
||||
public abstract fun genKeys ()Lme/proton/core/test/rule/annotation/TestUserData$GenKeys;
|
||||
public abstract fun mailboxPassword ()Ljava/lang/String;
|
||||
public abstract fun name ()Ljava/lang/String;
|
||||
public abstract fun password ()Ljava/lang/String;
|
||||
public abstract fun recoveryEmail ()Ljava/lang/String;
|
||||
public abstract fun recoveryPhone ()Ljava/lang/String;
|
||||
public abstract fun shouldSeed ()Z
|
||||
public abstract fun status ()Lme/proton/core/test/rule/annotation/TestUserData$Status;
|
||||
public abstract fun toTpSecret ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/annotation/TestUserData$Companion {
|
||||
public final fun getWithRandomUsername ()Lme/proton/core/test/rule/annotation/TestUserData;
|
||||
public final fun randomUsername ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/annotation/TestUserData$GenKeys : java/lang/Enum {
|
||||
public static final field Curve25519 Lme/proton/core/test/rule/annotation/TestUserData$GenKeys;
|
||||
public static final field None Lme/proton/core/test/rule/annotation/TestUserData$GenKeys;
|
||||
public static final field RSA2048 Lme/proton/core/test/rule/annotation/TestUserData$GenKeys;
|
||||
public static final field RSA4096 Lme/proton/core/test/rule/annotation/TestUserData$GenKeys;
|
||||
public static fun getEntries ()Lkotlin/enums/EnumEntries;
|
||||
public static fun valueOf (Ljava/lang/String;)Lme/proton/core/test/rule/annotation/TestUserData$GenKeys;
|
||||
public static fun values ()[Lme/proton/core/test/rule/annotation/TestUserData$GenKeys;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/annotation/TestUserData$Status : java/lang/Enum {
|
||||
public static final field Active Lme/proton/core/test/rule/annotation/TestUserData$Status;
|
||||
public static final field Admin Lme/proton/core/test/rule/annotation/TestUserData$Status;
|
||||
public static final field Deleted Lme/proton/core/test/rule/annotation/TestUserData$Status;
|
||||
public static final field Disabled Lme/proton/core/test/rule/annotation/TestUserData$Status;
|
||||
public static final field Super Lme/proton/core/test/rule/annotation/TestUserData$Status;
|
||||
public static final field VPNAdmin Lme/proton/core/test/rule/annotation/TestUserData$Status;
|
||||
public static fun getEntries ()Lkotlin/enums/EnumEntries;
|
||||
public static fun valueOf (Ljava/lang/String;)Lme/proton/core/test/rule/annotation/TestUserData$Status;
|
||||
public static fun values ()[Lme/proton/core/test/rule/annotation/TestUserData$Status;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/annotation/TestUserDataKt {
|
||||
public static final fun handleExternal (Lme/proton/core/test/rule/annotation/TestUserData;Ljava/lang/String;Ljava/lang/String;)Lme/proton/core/test/rule/annotation/TestUserData;
|
||||
public static synthetic fun handleExternal$default (Lme/proton/core/test/rule/annotation/TestUserData;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lme/proton/core/test/rule/annotation/TestUserData;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/di/TestEnvironmentConfigModule {
|
||||
public static final field INSTANCE Lme/proton/core/test/rule/di/TestEnvironmentConfigModule;
|
||||
public final fun getOverrideConfig ()Ljava/util/concurrent/atomic/AtomicReference;
|
||||
public final fun provideEnvironmentConfiguration ()Lme/proton/core/configuration/EnvironmentConfiguration;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/di/TestEnvironmentConfigModule_ProvideEnvironmentConfigurationFactory : dagger/internal/Factory {
|
||||
public fun <init> ()V
|
||||
public static fun create ()Lme/proton/core/test/rule/di/TestEnvironmentConfigModule_ProvideEnvironmentConfigurationFactory;
|
||||
public synthetic fun get ()Ljava/lang/Object;
|
||||
public fun get ()Lme/proton/core/configuration/EnvironmentConfiguration;
|
||||
public static fun provideEnvironmentConfiguration ()Lme/proton/core/configuration/EnvironmentConfiguration;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/extension/QuarkCommandKt {
|
||||
public static final fun seedTestUserData (Lme/proton/core/test/quark/v2/QuarkCommand;Lme/proton/core/test/rule/annotation/TestUserData;)Lme/proton/core/test/quark/response/CreateUserQuarkResponse;
|
||||
public static final fun setPaymentMethods (Lme/proton/core/test/quark/v2/QuarkCommand;Lme/proton/core/test/rule/annotation/TestPaymentMethods;)Lokhttp3/Response;
|
||||
public static final fun subscriptionCreate (Lme/proton/core/test/quark/v2/QuarkCommand;Lme/proton/core/test/rule/annotation/TestSubscriptionData;Ljava/lang/String;)Lokhttp3/Response;
|
||||
}
|
||||
|
||||
public final class me/proton/core/test/rule/extension/TestRuleKt {
|
||||
public static final fun protonRule (Ljava/lang/Object;[Lme/proton/core/test/rule/annotation/AnnotationTestData;Lme/proton/core/test/rule/annotation/EnvironmentConfig;Lme/proton/core/test/rule/annotation/TestUserData;ZZZLorg/junit/rules/TestRule;Lkotlin/jvm/functions/Function0;)Lme/proton/core/test/rule/ProtonRule;
|
||||
public static synthetic fun protonRule$default (Ljava/lang/Object;[Lme/proton/core/test/rule/annotation/AnnotationTestData;Lme/proton/core/test/rule/annotation/EnvironmentConfig;Lme/proton/core/test/rule/annotation/TestUserData;ZZZLorg/junit/rules/TestRule;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lme/proton/core/test/rule/ProtonRule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import studio.forface.easygradle.dsl.*
|
||||
import studio.forface.easygradle.dsl.android.*
|
||||
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
protonAndroidLibrary
|
||||
protonDagger
|
||||
kotlin("plugin.serialization")
|
||||
}
|
||||
|
||||
protonCoverage.disabled.set(true)
|
||||
publishOption.shouldBePublishedAsLib = true
|
||||
|
||||
android {
|
||||
namespace = "me.proton.core.test.rule"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(
|
||||
project(Module.configurationData),
|
||||
project(Module.configurationDaggerContentResolver),
|
||||
project(Module.quark),
|
||||
project(Module.authDomain),
|
||||
project(Module.authPresentation),
|
||||
`coroutines-android`,
|
||||
okhttp,
|
||||
junit,
|
||||
`hilt-android-testing`,
|
||||
`android-ktx`,
|
||||
`serialization-json`,
|
||||
`androidx-test-monitor`,
|
||||
`android-test-runner`,
|
||||
`compose-ui-test-junit`,
|
||||
`junit-ktx`
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.rule
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import dagger.hilt.android.EntryPointAccessors
|
||||
import me.proton.core.auth.domain.testing.LoginTestHelper
|
||||
import me.proton.core.auth.presentation.testing.ProtonTestEntryPoint
|
||||
import org.junit.rules.TestWatcher
|
||||
import org.junit.runner.Description
|
||||
|
||||
/**
|
||||
* A JUnit test rule for managing user authentication states before and after tests.
|
||||
* It utilizes [LoginTestHelper] for performing login and logout operations
|
||||
* based on the provided [ProtonRule.UserConfig].
|
||||
*/
|
||||
@SuppressLint("RestrictedApi")
|
||||
public class AuthenticationRule(
|
||||
private val userConfig: ProtonRule.UserConfig,
|
||||
) : TestWatcher() {
|
||||
|
||||
private val loginTestHelper: LoginTestHelper by lazy {
|
||||
protonTestEntryPoint.loginTestHelper
|
||||
}
|
||||
|
||||
private val protonTestEntryPoint by lazy {
|
||||
EntryPointAccessors.fromApplication(
|
||||
ApplicationProvider.getApplicationContext<Application>(),
|
||||
ProtonTestEntryPoint::class.java
|
||||
)
|
||||
}
|
||||
|
||||
override fun starting(description: Description) {
|
||||
if (userConfig.logoutBefore) {
|
||||
logout()
|
||||
}
|
||||
|
||||
userConfig.userData?.let {
|
||||
if (userConfig.loginBefore)
|
||||
loginTestHelper.login(it.name, it.password)
|
||||
}
|
||||
}
|
||||
|
||||
override fun finished(description: Description) {
|
||||
if (userConfig.logoutAfter) {
|
||||
logout()
|
||||
}
|
||||
}
|
||||
|
||||
private fun logout() {
|
||||
runCatching { loginTestHelper.logoutAll() }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.rule
|
||||
|
||||
import me.proton.core.configuration.EnvironmentConfiguration
|
||||
import me.proton.core.test.rule.annotation.EnvironmentConfig
|
||||
import me.proton.core.test.rule.annotation.configContractFieldsMap
|
||||
import me.proton.core.test.rule.di.TestEnvironmentConfigModule.overrideConfig
|
||||
import me.proton.core.test.rule.di.TestEnvironmentConfigModule.provideEnvironmentConfiguration
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.Description
|
||||
import org.junit.runners.model.Statement
|
||||
|
||||
/**
|
||||
* A test rule for setting up environment configuration before running tests.
|
||||
*
|
||||
* @property defaultConfig The default [EnvironmentConfig] to use for tests if no overrides are specified.
|
||||
* By default, it uses a configuration provided by [provideEnvironmentConfiguration].
|
||||
*/
|
||||
public class EnvironmentConfigRule(
|
||||
private val defaultConfig: EnvironmentConfig =
|
||||
EnvironmentConfig.fromConfiguration(provideEnvironmentConfiguration())
|
||||
) : TestRule {
|
||||
|
||||
/**
|
||||
* The active [EnvironmentConfig] for the current test. It is determined by looking for an
|
||||
* [EnvironmentConfig] annotation on the test method or class. If not found, [defaultConfig] is used.
|
||||
*
|
||||
* This property is initialized when the rule is applied and is accessible during the test execution.
|
||||
*/
|
||||
public lateinit var config: EnvironmentConfig
|
||||
private set
|
||||
|
||||
/**
|
||||
* Applies the environment configuration for the test described by [description].
|
||||
*/
|
||||
override fun apply(base: Statement, description: Description): Statement {
|
||||
config = description.getAnnotation(EnvironmentConfig::class.java) ?: defaultConfig
|
||||
EnvironmentConfiguration.fromMap(config.configContractFieldsMap).apply(overrideConfig::set)
|
||||
return base
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.rule
|
||||
|
||||
import dagger.hilt.android.testing.HiltAndroidRule
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import me.proton.core.test.rule.annotation.AnnotationTestData
|
||||
import me.proton.core.test.rule.annotation.EnvironmentConfig
|
||||
import me.proton.core.test.rule.annotation.TestUserData
|
||||
import me.proton.core.test.rule.di.TestEnvironmentConfigModule.provideEnvironmentConfiguration
|
||||
import org.junit.rules.ExternalResource
|
||||
import org.junit.rules.RuleChain
|
||||
import org.junit.rules.TestRule
|
||||
import org.junit.runner.Description
|
||||
import org.junit.runners.model.Statement
|
||||
|
||||
/**
|
||||
* Base class for custom test rules in the Proton framework.
|
||||
*
|
||||
* Provides a structured approach to managing various aspects of test setup and execution:
|
||||
*
|
||||
* - **Environment configuration:** Manages environment configuration using `EnvironmentConfigRule`.
|
||||
* - **Hilt dependencies:** Handles Hilt dependency injection using `HiltAndroidRule`.
|
||||
* - **Test data:** Provides test data management through `QuarkTestDataRule`.
|
||||
* - **User authentication:** Optionally enables user authentication with `AuthenticationRule`
|
||||
* based on provided `TestUserData`.
|
||||
* - **User-defined setup:** Allows executing custom setup logic before each test through a provided lambda function.
|
||||
*
|
||||
* @param userConfig Configuration for user data and related behavior (e.g., login/logout settings).
|
||||
* @param testConfig Configuration for environment, test data, and an optional activity rule.
|
||||
* @param hiltTestInstance Hilt test instance for dependency injection.
|
||||
* @param setup A lambda function containing setup logic to be executed before each test.
|
||||
*/
|
||||
public open class ProtonRule(
|
||||
private val userConfig: UserConfig,
|
||||
private val testConfig: TestConfig,
|
||||
private val hiltTestInstance: Any,
|
||||
private val setup: () -> Any
|
||||
) : TestRule {
|
||||
|
||||
private val environmentConfigRule by lazy {
|
||||
val envConfig = testConfig.envConfig ?: EnvironmentConfig.fromConfiguration(provideEnvironmentConfiguration())
|
||||
EnvironmentConfigRule(envConfig)
|
||||
}
|
||||
|
||||
private val hiltRule by lazy {
|
||||
HiltAndroidRule(hiltTestInstance)
|
||||
}
|
||||
|
||||
public val testDataRule: QuarkTestDataRule by lazy {
|
||||
QuarkTestDataRule(
|
||||
*testConfig.annotationTestData,
|
||||
initialTestUserData = userConfig.userData,
|
||||
environmentConfig = { environmentConfigRule.config }
|
||||
)
|
||||
}
|
||||
|
||||
private val authenticationRule by lazy {
|
||||
userConfig
|
||||
.takeUnless { it.userData == null }
|
||||
?.let {
|
||||
AuthenticationRule(it)
|
||||
}
|
||||
}
|
||||
|
||||
private val setupRule by lazy {
|
||||
before { setup() }
|
||||
}
|
||||
|
||||
private val ruleChain: RuleChain by lazy {
|
||||
RuleChain.outerRule(environmentConfigRule)
|
||||
.around(hiltRule)
|
||||
.around(setupRule)
|
||||
.around(testDataRule)
|
||||
.aroundNullable(authenticationRule)
|
||||
.aroundNullable(testConfig.activityRule)
|
||||
}
|
||||
|
||||
override fun apply(base: Statement, description: Description): Statement = ruleChain.apply(base, description)
|
||||
|
||||
public data class UserConfig(
|
||||
val userData: TestUserData? = null,
|
||||
val loginBefore: Boolean = true,
|
||||
val logoutBefore: Boolean = true,
|
||||
val logoutAfter: Boolean = true
|
||||
) {
|
||||
val overrideLogin: Boolean get() = loginBefore || logoutBefore || logoutAfter
|
||||
}
|
||||
|
||||
public data class TestConfig(
|
||||
val envConfig: EnvironmentConfig? = null,
|
||||
val annotationTestData: Array<out AnnotationTestData<Annotation>> = emptyArray(),
|
||||
val activityRule: TestRule? = null,
|
||||
)
|
||||
|
||||
private fun RuleChain.aroundNullable(rule: TestRule?): RuleChain {
|
||||
return around(rule ?: return this)
|
||||
}
|
||||
}
|
||||
|
||||
public fun <T> T.before(block: suspend T.() -> Any): ExternalResource =
|
||||
object : ExternalResource() {
|
||||
override fun before() {
|
||||
runBlocking {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.rule
|
||||
|
||||
import me.proton.core.configuration.EnvironmentConfiguration
|
||||
import me.proton.core.test.quark.response.CreateUserQuarkResponse
|
||||
import me.proton.core.test.quark.v2.QuarkCommand
|
||||
import me.proton.core.test.rule.annotation.AnnotationTestData
|
||||
import me.proton.core.test.rule.annotation.EnvironmentConfig
|
||||
import me.proton.core.test.rule.annotation.TestUserData
|
||||
import me.proton.core.test.rule.annotation.handleExternal
|
||||
import me.proton.core.test.rule.annotation.toEnvironmentConfiguration
|
||||
import me.proton.core.test.rule.extension.seedTestUserData
|
||||
import okhttp3.OkHttpClient
|
||||
import org.junit.rules.TestWatcher
|
||||
import org.junit.runner.Description
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import kotlin.time.toJavaDuration
|
||||
|
||||
/**
|
||||
* A JUnit test rule that manages test data setup and teardown using Quark commands for configuring test environments
|
||||
* and user data. This rule facilitates dynamic application of test data and environment configurations based
|
||||
* on annotations or provided initial settings, ensuring tests run with the required setup.
|
||||
*
|
||||
* @property initialTestUserData Initial user data to set up before tests. Can be overridden by test-specific
|
||||
* annotations.
|
||||
* @property environmentConfig A lambda expression that supplies the [EnvironmentConfig] used for test execution.
|
||||
*/
|
||||
public class QuarkTestDataRule(
|
||||
private vararg val annotationTestData: AnnotationTestData<Annotation>,
|
||||
initialTestUserData: TestUserData?,
|
||||
private val environmentConfig: () -> EnvironmentConfig
|
||||
) : TestWatcher() {
|
||||
|
||||
private lateinit var quarkCommand: QuarkCommand
|
||||
|
||||
private val environmentConfiguration: EnvironmentConfiguration by lazy {
|
||||
environmentConfig().toEnvironmentConfiguration()
|
||||
}
|
||||
|
||||
private var createdUserResponse: CreateUserQuarkResponse? = null
|
||||
|
||||
private val testDataMap: MutableMap<Class<out Annotation>, Annotation> = mutableMapOf()
|
||||
|
||||
/**
|
||||
* The user data applied to the current test, initially set from [initialTestUserData] and potentially
|
||||
* overridden by test-specific annotations.
|
||||
*/
|
||||
public var testUserData: TestUserData? = initialTestUserData?.handleExternal()
|
||||
private set
|
||||
|
||||
/**
|
||||
* Prepares and applies test data and configurations before each test starts. This includes setting up
|
||||
* user/env data and processing all test data entries against the test's annotations.
|
||||
*/
|
||||
override fun starting(description: Description) {
|
||||
quarkCommand = QuarkCommand(quarkClient)
|
||||
.baseUrl("https://${environmentConfiguration.host}/api/internal")
|
||||
.proxyToken(environmentConfiguration.proxyToken)
|
||||
|
||||
testUserData = description.getAnnotation(TestUserData::class.java)?.handleExternal() ?: testUserData
|
||||
|
||||
testUserData?.takeIf { it.shouldSeed }?.apply {
|
||||
createdUserResponse = quarkCommand.seedTestUserData(this)
|
||||
}
|
||||
|
||||
annotationTestData.forEach { entry ->
|
||||
val annotationData = description.getAnnotation(entry.annotationClass) ?: entry.default
|
||||
entry.implementation(quarkCommand, annotationData, testUserData, createdUserResponse)
|
||||
testDataMap[entry.annotationClass] = annotationData
|
||||
}
|
||||
}
|
||||
|
||||
/** Clean up test data and configurations after each test finishes. **/
|
||||
override fun finished(description: Description) {
|
||||
annotationTestData.forEach { data ->
|
||||
testDataMap[data.annotationClass]?.let {
|
||||
data.tearDown?.invoke(
|
||||
quarkCommand,
|
||||
it,
|
||||
testUserData,
|
||||
createdUserResponse
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Retrieves test data of a specific annotation type, if applied to the current test. **/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public fun <T : Annotation> getTestData(annotationClass: Class<T>): T = testDataMap[annotationClass] as T
|
||||
|
||||
private val AnnotationTestData<Annotation>.annotationClass: Class<out Annotation>
|
||||
get() = default.annotationClass.java
|
||||
|
||||
public companion object {
|
||||
public val quarkClientTimeout: AtomicReference<Duration> = AtomicReference(60.seconds)
|
||||
|
||||
private val quarkClient: OkHttpClient by lazy {
|
||||
OkHttpClient.Builder()
|
||||
.connectTimeout(quarkClientTimeout.get().toJavaDuration())
|
||||
.readTimeout(quarkClientTimeout.get().toJavaDuration())
|
||||
.writeTimeout(quarkClientTimeout.get().toJavaDuration())
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.rule.annotation
|
||||
|
||||
import me.proton.core.test.quark.response.CreateUserQuarkResponse
|
||||
import me.proton.core.test.quark.v2.QuarkCommand
|
||||
|
||||
/**
|
||||
* Represents a test data configuration for the `QuarkTestDataRule`.
|
||||
*
|
||||
* @param T The annotation type associated with this test data configuration.
|
||||
* @param default The default annotation instance to use if no test-specific annotation is present.
|
||||
* @param implementation A lambda function defining how to apply the test data using the provided Quark command,
|
||||
* test user data (if available), and created user response (if available).
|
||||
* @param tearDown An optional lambda function defining how to tear down the test data after the test, using the
|
||||
* provided Quark command, test data annotation, test user data (if available),
|
||||
* and created user response (if available).
|
||||
*/
|
||||
public class AnnotationTestData<T: Annotation>(
|
||||
public val default: T,
|
||||
public val implementation: QuarkCommand.(T, TestUserData?, CreateUserQuarkResponse?) -> Any,
|
||||
public val tearDown: (QuarkCommand.(T, TestUserData?, CreateUserQuarkResponse?) -> Unit)? = null,
|
||||
) {
|
||||
|
||||
/**
|
||||
* Convenience constructor allowing specifying implementation without requiring test user data.
|
||||
*
|
||||
* @param default The default annotation instance to use.
|
||||
* @param implementation A lambda function defining how to apply the test data using the provided Quark command
|
||||
* and test data annotation.
|
||||
* @param tearDown An optional lambda function defining how to tear down the test data after the test,
|
||||
* using the provided Quark command and test data annotation.
|
||||
*/
|
||||
public constructor(
|
||||
default: T,
|
||||
implementation: QuarkCommand.(T) -> Any,
|
||||
tearDown: (QuarkCommand.(T) -> Unit)? = null
|
||||
) : this(
|
||||
default = default,
|
||||
implementation = { data, _, _ -> implementation(data) },
|
||||
tearDown = { data, _, _ -> tearDown?.invoke(this, data) }
|
||||
)
|
||||
|
||||
/**
|
||||
* Convenience constructor allowing specifying implementation with only CreateUserQuarkResponse.
|
||||
*
|
||||
* @param default The default annotation instance to use.
|
||||
* @param implementation A lambda function defining how to apply the test data using the provided Quark command
|
||||
* and created user response.
|
||||
* @param tearDown An optional lambda function defining how to tear down the test data after the test,
|
||||
* using the provided Quark command and created user response.
|
||||
*/
|
||||
public constructor(
|
||||
default: T,
|
||||
implementation: QuarkCommand.(T, CreateUserQuarkResponse) -> Any,
|
||||
tearDown: (QuarkCommand.(T, CreateUserQuarkResponse) -> Unit)? = null
|
||||
) : this(
|
||||
default = default,
|
||||
implementation = { data, _, seededUser ->
|
||||
implementation(
|
||||
data,
|
||||
seededUser ?: error("Cannot seed test data - TestUserData is not provided.")
|
||||
)
|
||||
},
|
||||
tearDown = { data, _, seededUser ->
|
||||
tearDown?.invoke(
|
||||
this,
|
||||
data,
|
||||
seededUser ?: error("Cannot tear down test data - TestUserData is not provided.")
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.rule.annotation
|
||||
|
||||
import me.proton.core.configuration.EnvironmentConfiguration
|
||||
|
||||
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
public annotation class EnvironmentConfig(
|
||||
public val host: String
|
||||
) {
|
||||
public companion object {
|
||||
public fun fromConfiguration(config: EnvironmentConfiguration): EnvironmentConfig =
|
||||
EnvironmentConfig(config.host)
|
||||
}
|
||||
}
|
||||
|
||||
public val EnvironmentConfig.configContractFieldsMap: Map<String, String?>
|
||||
get() = mapOf(::host.name to host)
|
||||
|
||||
public fun EnvironmentConfig.toEnvironmentConfiguration(): EnvironmentConfiguration =
|
||||
EnvironmentConfiguration.fromMap(configContractFieldsMap)
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.rule.annotation
|
||||
|
||||
import me.proton.core.domain.entity.AppStore
|
||||
import me.proton.core.test.quark.v2.command.setPaymentMethods
|
||||
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
public annotation class TestPaymentMethods(
|
||||
val appStore: AppStore = AppStore.GooglePlay,
|
||||
val card: Boolean = true,
|
||||
val paypal: Boolean = true,
|
||||
val inApp: Boolean = true
|
||||
)
|
||||
|
||||
public val TestPaymentMethods.annotationTestData: AnnotationTestData<TestPaymentMethods>
|
||||
get() = AnnotationTestData(
|
||||
this,
|
||||
implementation = { data ->
|
||||
setPaymentMethods(
|
||||
data.appStore,
|
||||
data.card,
|
||||
data.paypal,
|
||||
data.inApp
|
||||
)
|
||||
},
|
||||
tearDown = { _ ->
|
||||
setPaymentMethods(
|
||||
card = true,
|
||||
paypal = true,
|
||||
inApp = true
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.rule.annotation
|
||||
|
||||
import me.proton.core.test.quark.data.Plan
|
||||
import me.proton.core.test.quark.response.CreateUserQuarkResponse
|
||||
import me.proton.core.test.rule.extension.subscriptionCreate
|
||||
import me.proton.core.util.kotlin.EMPTY_STRING
|
||||
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
public annotation class TestSubscriptionData(
|
||||
val plan: Plan = Plan.Free,
|
||||
val couponCode: String = EMPTY_STRING,
|
||||
val delinquent: Boolean = false
|
||||
)
|
||||
|
||||
public val TestSubscriptionData.annotationTestData: AnnotationTestData<TestSubscriptionData>
|
||||
get() = AnnotationTestData(
|
||||
default = this,
|
||||
implementation = { data: TestSubscriptionData, seededUser: CreateUserQuarkResponse? ->
|
||||
seededUser?.let {
|
||||
subscriptionCreate(data, it.decryptedUserId.toString())
|
||||
} ?: error("Could not create subscription. User is not seeded.")
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.rule.annotation
|
||||
|
||||
import me.proton.core.util.kotlin.EMPTY_STRING
|
||||
import me.proton.core.util.kotlin.random
|
||||
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@Suppress("LongParameterList")
|
||||
public annotation class TestUserData(
|
||||
val name: String = EMPTY_STRING,
|
||||
val password: String = "password",
|
||||
val recoveryEmail: String = EMPTY_STRING,
|
||||
val status: Status = Status.Active,
|
||||
val authVersion: Int = 4,
|
||||
val createAddress: Boolean = true,
|
||||
val genKeys: GenKeys = GenKeys.Curve25519,
|
||||
val mailboxPassword: String = EMPTY_STRING,
|
||||
val external: Boolean = false,
|
||||
val toTpSecret: String = EMPTY_STRING,
|
||||
val recoveryPhone: String = EMPTY_STRING,
|
||||
val externalEmail: String = EMPTY_STRING,
|
||||
|
||||
val shouldSeed: Boolean = true,
|
||||
) {
|
||||
public enum class Status {
|
||||
Deleted, Disabled, Active, VPNAdmin, Admin, Super
|
||||
}
|
||||
|
||||
public enum class GenKeys {
|
||||
None, RSA2048, RSA4096, Curve25519
|
||||
}
|
||||
|
||||
public companion object {
|
||||
public fun randomUsername(): String =
|
||||
arrayOf(('A'..'Z').toList(), ('1'..'9').toList())
|
||||
.map { String.random(length = 4, charPool = it) }
|
||||
.let { "proton${it[0]}${it[1]}" }
|
||||
|
||||
public val withRandomUsername: TestUserData get() = TestUserData(randomUsername())
|
||||
}
|
||||
}
|
||||
|
||||
public fun TestUserData.handleExternal(
|
||||
username: String = TestUserData.randomUsername(),
|
||||
extEmail: String = "${TestUserData.randomUsername()}@example.lt"
|
||||
): TestUserData = TestUserData(
|
||||
name = if (name.isEmpty() && external) name else username,
|
||||
password,
|
||||
recoveryEmail,
|
||||
status,
|
||||
authVersion,
|
||||
createAddress,
|
||||
genKeys,
|
||||
mailboxPassword,
|
||||
external,
|
||||
toTpSecret,
|
||||
recoveryPhone,
|
||||
externalEmail = if (externalEmail.isEmpty() && external) extEmail else externalEmail
|
||||
)
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.rule.di
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import dagger.hilt.testing.TestInstallIn
|
||||
import me.proton.core.configuration.EnvironmentConfiguration
|
||||
import me.proton.core.configuration.dagger.ContentResolverEnvironmentConfigModule
|
||||
import me.proton.core.configuration.extension.configContractFieldsMap
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@TestInstallIn(
|
||||
components = [SingletonComponent::class],
|
||||
replaces = [ContentResolverEnvironmentConfigModule::class]
|
||||
)
|
||||
public object TestEnvironmentConfigModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
public fun provideEnvironmentConfiguration(): EnvironmentConfiguration =
|
||||
InstrumentationRegistry
|
||||
.getArguments()
|
||||
.configFields()
|
||||
.takeIf { it.isNotEmpty() }
|
||||
?.let {
|
||||
EnvironmentConfiguration.fromMap(it)
|
||||
} ?: EnvironmentConfiguration(::getConfigValue)
|
||||
|
||||
|
||||
public val overrideConfig: AtomicReference<EnvironmentConfiguration?> = AtomicReference(null)
|
||||
|
||||
private val defaultConfig = EnvironmentConfiguration.fromClass()
|
||||
|
||||
private fun getConfigValue(key: String): String {
|
||||
val defaultValue = defaultConfig.configContractFieldsMap[key].toString()
|
||||
val overrideValue = overrideConfig.get()?.configContractFieldsMap?.get(key)?.toString()
|
||||
return overrideValue ?: defaultValue
|
||||
}
|
||||
|
||||
private fun Bundle.configFields(): Map<String, Any?> {
|
||||
val hostKey = EnvironmentConfiguration::host.name
|
||||
val proxyTokenKey = EnvironmentConfiguration::proxyToken.name
|
||||
return mapOf(
|
||||
hostKey to (getString(hostKey) ?: getConfigValue(hostKey)),
|
||||
proxyTokenKey to (getString(proxyTokenKey) ?: getConfigValue(proxyTokenKey))
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.rule.extension
|
||||
|
||||
import kotlinx.serialization.StringFormat
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import me.proton.core.test.quark.response.CreateUserQuarkResponse
|
||||
import me.proton.core.test.quark.v2.QuarkCommand
|
||||
import me.proton.core.test.quark.v2.command.USERS_CREATE
|
||||
import me.proton.core.test.quark.v2.command.setPaymentMethods
|
||||
import me.proton.core.test.quark.v2.toEncodedArgs
|
||||
import me.proton.core.test.rule.annotation.TestPaymentMethods
|
||||
import me.proton.core.test.rule.annotation.TestSubscriptionData
|
||||
import me.proton.core.test.rule.annotation.TestUserData
|
||||
import me.proton.core.util.kotlin.EMPTY_STRING
|
||||
import okhttp3.Response
|
||||
|
||||
public fun QuarkCommand.setPaymentMethods(methods: TestPaymentMethods): Response =
|
||||
setPaymentMethods(
|
||||
methods.appStore,
|
||||
methods.card,
|
||||
methods.paypal,
|
||||
methods.inApp
|
||||
)
|
||||
|
||||
public fun QuarkCommand.seedTestUserData(data: TestUserData): CreateUserQuarkResponse {
|
||||
val args = listOf(
|
||||
"-N" to data.name,
|
||||
"-p" to data.password,
|
||||
"-c" to data.createAddress.trueOrEmpty(),
|
||||
"-r" to data.recoveryEmail,
|
||||
"-s" to data.status.ordinal.toString(),
|
||||
"-a" to data.authVersion.toString(),
|
||||
"-c" to data.createAddress.trueOrEmpty(),
|
||||
"-k" to data.genKeys.valueOrEmpty(),
|
||||
"-m" to data.mailboxPassword,
|
||||
"-e" to data.external.trueOrEmpty(),
|
||||
"-ts" to data.toTpSecret,
|
||||
"-rp" to data.recoveryPhone,
|
||||
"-em" to data.externalEmail,
|
||||
"--format" to "json"
|
||||
).toEncodedArgs(ignoreEmpty = true)
|
||||
|
||||
return route(USERS_CREATE)
|
||||
.args(args)
|
||||
.build()
|
||||
.let {
|
||||
client.executeQuarkRequest(it)
|
||||
}
|
||||
.let {
|
||||
json.tryDecodeResponseBody(it)
|
||||
}
|
||||
}
|
||||
|
||||
public fun QuarkCommand.subscriptionCreate(
|
||||
subscription: TestSubscriptionData,
|
||||
decryptedUserId: String
|
||||
): Response =
|
||||
route("quark/raw::user:create:subscription")
|
||||
.args(
|
||||
listOf(
|
||||
"userID" to decryptedUserId,
|
||||
"--planID" to subscription.plan.planName,
|
||||
"--couponCode" to subscription.couponCode,
|
||||
"--cycle" to subscription.delinquent.trueOrEmpty(),
|
||||
"--format" to "json"
|
||||
).toEncodedArgs()
|
||||
)
|
||||
.build()
|
||||
.let {
|
||||
client.executeQuarkRequest(it)
|
||||
}
|
||||
|
||||
private fun Boolean.trueOrEmpty() = if (this) toString() else EMPTY_STRING
|
||||
|
||||
private fun TestUserData.GenKeys.valueOrEmpty() = if (this != TestUserData.GenKeys.None) toString() else EMPTY_STRING
|
||||
|
||||
private fun StringFormat.tryDecodeResponseBody(response: Response): CreateUserQuarkResponse {
|
||||
val responseString = response.body!!.string()
|
||||
return try {
|
||||
decodeFromString(responseString)
|
||||
} catch (ex: Exception) {
|
||||
error(responseString)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.test.rule.extension
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.ui.test.junit4.ComposeTestRule
|
||||
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||
import androidx.test.ext.junit.rules.activityScenarioRule
|
||||
import me.proton.core.test.rule.ProtonRule
|
||||
import me.proton.core.test.rule.annotation.AnnotationTestData
|
||||
import me.proton.core.test.rule.annotation.EnvironmentConfig
|
||||
import me.proton.core.test.rule.annotation.TestUserData
|
||||
import org.junit.rules.TestRule
|
||||
|
||||
/**
|
||||
* Creates a `ProtonRule` instance for managing test setup and execution.
|
||||
*
|
||||
* This function offers fine-grained control over various test aspects, including:
|
||||
* - Environment configuration
|
||||
* - Test data
|
||||
* - User authentication
|
||||
* - Custom setup logic
|
||||
* - Activity or Compose test rule
|
||||
*
|
||||
* @param annotationTestData Array of `AnnotationTestData` for `QuarkTestDataRule`.
|
||||
* @param envConfig Environment configuration for the test (optional).
|
||||
* @param userData Test user data (optional).
|
||||
* @param loginBefore Whether to perform login before the test (default: false).
|
||||
* @param logoutBefore Whether to perform logout before the test (default: false).
|
||||
* @param logoutAfter Whether to perform logout after the test (default: false).
|
||||
* @param activityRule Optional `TestRule` for managing activities (default: null).
|
||||
* @param setUp A lambda function containing setup logic to be executed before each test (default: empty).
|
||||
* @return A new `ProtonRule` instance.
|
||||
*/
|
||||
@SuppressWarnings("LongParameterList")
|
||||
public fun Any.protonRule(
|
||||
vararg annotationTestData: AnnotationTestData<Annotation>,
|
||||
envConfig: EnvironmentConfig? = null,
|
||||
userData: TestUserData? = null,
|
||||
loginBefore: Boolean = false,
|
||||
logoutBefore: Boolean = false,
|
||||
logoutAfter: Boolean = false,
|
||||
activityRule: TestRule? = null,
|
||||
setUp: () -> Any = { },
|
||||
): ProtonRule {
|
||||
val userConfig = ProtonRule.UserConfig(
|
||||
userData = userData,
|
||||
loginBefore = loginBefore,
|
||||
logoutBefore = logoutBefore,
|
||||
logoutAfter = logoutAfter
|
||||
)
|
||||
|
||||
val testConfig = ProtonRule.TestConfig(
|
||||
envConfig = envConfig,
|
||||
annotationTestData = annotationTestData,
|
||||
activityRule = activityRule
|
||||
)
|
||||
|
||||
return ProtonRule(
|
||||
userConfig = userConfig,
|
||||
testConfig = testConfig,
|
||||
hiltTestInstance = this,
|
||||
setup = setUp
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a `ProtonRule` instance with an `ActivityScenarioRule` for a specific activity type.
|
||||
*
|
||||
* This function inherits all features of `protonRule` and uses the provided `ActivityScenarioRule`
|
||||
* for managing the activity lifecycle within the test.
|
||||
*
|
||||
* @param A The type of activity to be used with the `ActivityScenarioRule`.
|
||||
* @param annotationTestData Array of `AnnotationTestData` for `QuarkTestDataRule`.
|
||||
* @param envConfig Environment configuration for the test (optional).
|
||||
* @param userData Test user data (optional).
|
||||
* @param loginBefore Whether to perform login before the test (default: true).
|
||||
* @param logoutBefore Whether to perform logout before the test (default: true).
|
||||
* @param logoutAfter Whether to perform logout after the test (default: true).
|
||||
* @param activityScenarioRule An `ActivityScenarioRule` for the specified activity type
|
||||
* (default: created using `activityScenarioRule()`).
|
||||
* @param setUp A lambda function containing setup logic to be executed before each test (default: empty).
|
||||
* @return A new `ProtonRule` instance.
|
||||
*/
|
||||
@SuppressWarnings("LongParameterList")
|
||||
public inline fun <reified A : Activity> Any.protonActivityScenarioRule(
|
||||
vararg annotationTestData: AnnotationTestData<Annotation>,
|
||||
envConfig: EnvironmentConfig? = null,
|
||||
userData: TestUserData? = TestUserData.withRandomUsername,
|
||||
loginBefore: Boolean = true,
|
||||
logoutBefore: Boolean = true,
|
||||
logoutAfter: Boolean = true,
|
||||
activityScenarioRule: ActivityScenarioRule<A> = activityScenarioRule(),
|
||||
noinline setUp: () -> Any = { },
|
||||
): ProtonRule = protonRule(
|
||||
annotationTestData = annotationTestData,
|
||||
envConfig = envConfig,
|
||||
userData = userData,
|
||||
loginBefore = loginBefore,
|
||||
logoutBefore = logoutBefore,
|
||||
logoutAfter = logoutAfter,
|
||||
activityRule = activityScenarioRule,
|
||||
setUp = setUp
|
||||
)
|
||||
|
||||
/**
|
||||
* Creates a `ProtonRule` instance with a `ComposeTestRule` for an Android Compose component activity.
|
||||
*
|
||||
* This function inherits all features of `protonRule` and uses the provided `ComposeTestRule`
|
||||
* for managing the Compose UI during the test.
|
||||
*
|
||||
* @param A The type of component activity to be used with the `ComposeTestRule`.
|
||||
* @param annotationTestData Array of `AnnotationTestData` for `QuarkTestDataRule`.
|
||||
* @param envConfig Environment configuration for the test (optional).
|
||||
* @param userData Test user data (optional).
|
||||
* @param loginBefore Whether to perform login before the test (default: true).
|
||||
* @param logoutBefore Whether to perform logout before the test (default: true).
|
||||
* @param logoutAfter Whether to perform logout after the test (default: true).
|
||||
* @param composeTestRule A `ComposeTestRule` for the specified component activity type
|
||||
* (default: created using `createAndroidComposeRule()`).
|
||||
* @param setUp A lambda function containing setup logic to be executed before each test (default: empty).
|
||||
* @return A new `ProtonRule` instance.
|
||||
*/
|
||||
@SuppressWarnings("LongParameterList")
|
||||
public inline fun <reified A : ComponentActivity> Any.protonAndroidComposeRule(
|
||||
vararg annotationTestData: AnnotationTestData<Annotation>,
|
||||
envConfig: EnvironmentConfig? = null,
|
||||
userData: TestUserData? = TestUserData.withRandomUsername,
|
||||
loginBefore: Boolean = true,
|
||||
logoutBefore: Boolean = true,
|
||||
logoutAfter: Boolean = true,
|
||||
composeTestRule: ComposeTestRule = createAndroidComposeRule<A>(),
|
||||
noinline setUp: () -> Any = { },
|
||||
): ProtonRule = protonRule(
|
||||
annotationTestData = annotationTestData,
|
||||
envConfig = envConfig,
|
||||
userData = userData,
|
||||
loginBefore = loginBefore,
|
||||
logoutBefore = logoutBefore,
|
||||
logoutAfter = logoutAfter,
|
||||
activityRule = composeTestRule,
|
||||
setUp = setUp
|
||||
)
|
||||
Reference in New Issue
Block a user