diff --git a/.gitignore b/.gitignore index deb053916c..d59a86bc09 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,3 @@ local.properties /compile.sh /ctest.sh /test.sh - diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 41125a7ec8..0d4295b43b 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,8 +1,11 @@ - + diff --git a/FlowCrypt/lint.xml b/FlowCrypt/lint.xml index e711fecc96..ff5696c26b 100644 --- a/FlowCrypt/lint.xml +++ b/FlowCrypt/lint.xml @@ -20,4 +20,4 @@ - \ No newline at end of file + diff --git a/FlowCrypt/src/androidTest/assets/messages/mime/8bit-utf8.txt b/FlowCrypt/src/androidTest/assets/messages/mime/8bit-utf8.txt index 6d7bc7a068..44a4b18bca 100644 --- a/FlowCrypt/src/androidTest/assets/messages/mime/8bit-utf8.txt +++ b/FlowCrypt/src/androidTest/assets/messages/mime/8bit-utf8.txt @@ -17,4 +17,3 @@ Content-Transfer-Encoding: 8bit Text: Ваше оголошення - diff --git a/FlowCrypt/src/androidTest/assets/messages/mime/encrypted_msg_info_plain_text_error_badly_formatted.txt b/FlowCrypt/src/androidTest/assets/messages/mime/encrypted_msg_info_plain_text_error_badly_formatted.txt index 1496bc80d1..a77888b188 100644 --- a/FlowCrypt/src/androidTest/assets/messages/mime/encrypted_msg_info_plain_text_error_badly_formatted.txt +++ b/FlowCrypt/src/androidTest/assets/messages/mime/encrypted_msg_info_plain_text_error_badly_formatted.txt @@ -71,4 +71,3 @@ vT56K5RcJnyZkFMaxqqKa6qBJ7XXL3nn2ePquNwj3zO59yVoF2AeoipJCTLE C/jf1vpjTJlbneWAjUWjm8+SlfCY1V/oERo= =UCCQ -----END PGP MESSAGE----- - diff --git a/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_and_pub_keys_armored_own_header.asc b/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_and_pub_keys_armored_own_header.asc index a38f1632c2..227875fc6d 100644 --- a/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_and_pub_keys_armored_own_header.asc +++ b/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_and_pub_keys_armored_own_header.asc @@ -161,4 +161,3 @@ YHAmeAIbDAUWAgMBAAQLCQgHBRUKCQgLAh4BAAoJEMyEq3t0m4PryFkA/jZ7HuJK qH98S9dQSRizw3hxAg== =g+Is -----END PGP PRIVATE KEY BLOCK----- - diff --git a/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_and_pub_keys_armored_own_with_single_header.asc b/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_and_pub_keys_armored_own_with_single_header.asc index 53414a55cd..b198cc12fa 100644 --- a/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_and_pub_keys_armored_own_with_single_header.asc +++ b/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_and_pub_keys_armored_own_with_single_header.asc @@ -121,4 +121,3 @@ q00PAwEIB4h1BBgWCgAdBQJgcCU5AhsMBRYCAwEABAsJCAcFFQoJCAsCHgEACgkQ 0oMmO25amIOvw4zoOJDypIQ+wNp+62iNde0pukwP =8kgY -----END PGP PUBLIC KEY BLOCK----- - diff --git a/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_keys_armored_own_header.asc b/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_keys_armored_own_header.asc index f439702519..7a47256fa5 100644 --- a/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_keys_armored_own_header.asc +++ b/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_keys_armored_own_header.asc @@ -177,4 +177,3 @@ oPnfUupWCMKXM3PN/Sw6Zn5Zja3DRuFxrSXIAQCOXPE4EOucuOmMCi2JcfkVmpfE ReZjtUMWEusItbv4Cg== =I9MB -----END PGP PRIVATE KEY BLOCK----- - diff --git a/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_keys_armored_own_with_single_header.asc b/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_keys_armored_own_with_single_header.asc index 1a4c3cf464..bdf7c12278 100644 --- a/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_keys_armored_own_with_single_header.asc +++ b/FlowCrypt/src/androidTest/assets/pgp/keys/10_prv_keys_armored_own_with_single_header.asc @@ -142,4 +142,3 @@ z++0ULA1AQDAfGX9fWSFkFJeUEMf3wdtH4f7uBnpHFed9T7ccHh1hgD/YkNbtpMI EdJrIZnU/alchpAYC5JRJuaoyuaOgWxAgQI= =E5rK -----END PGP PRIVATE KEY BLOCK----- - diff --git a/FlowCrypt/src/androidTest/assets/pgp/keys/10_pub_keys_armored_own_header.asc b/FlowCrypt/src/androidTest/assets/pgp/keys/10_pub_keys_armored_own_header.asc index 1290910709..df8c532790 100644 --- a/FlowCrypt/src/androidTest/assets/pgp/keys/10_pub_keys_armored_own_header.asc +++ b/FlowCrypt/src/androidTest/assets/pgp/keys/10_pub_keys_armored_own_header.asc @@ -137,4 +137,3 @@ CAsCHgEACgkQCW1r0sdsyuuVRQD/TsQc21Kg+d9S6lYIwpczc839LDpmflmNrcNG 4XGtJcgBAI5c8TgQ65y46YwKLYlx+RWal8RF5mO1QxYS6wi1u/gK =tPlZ -----END PGP PUBLIC KEY BLOCK----- - diff --git a/FlowCrypt/src/androidTest/assets/pgp/keys/10_pub_keys_armored_own_with_single_header.asc b/FlowCrypt/src/androidTest/assets/pgp/keys/10_pub_keys_armored_own_with_single_header.asc index 1c31205b4a..7b27b5f8f8 100644 --- a/FlowCrypt/src/androidTest/assets/pgp/keys/10_pub_keys_armored_own_with_single_header.asc +++ b/FlowCrypt/src/androidTest/assets/pgp/keys/10_pub_keys_armored_own_with_single_header.asc @@ -107,4 +107,3 @@ YHADnhIKKwYBBAGXVQEFAQEHQCL+4AjWCMUzWCsMmSJGF3WcUNOLFNR4zWsLtJl2 W7aTCBHSayGZ1P2pXIaQGAuSUSbmqMrmjoFsQIEC =wEh7 -----END PGP PUBLIC KEY BLOCK----- - diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/DebugTestingTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/DebugTestingTest.kt index 05287a40d1..4b5191f3d4 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/DebugTestingTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/DebugTestingTest.kt @@ -28,4 +28,4 @@ class DebugTestingTest { @Test fun alwaysSuccessTestSecond() { } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/base/BaseActivityTestImplementation.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/base/BaseActivityTestImplementation.kt index e67c4eafb6..03a869e6fb 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/base/BaseActivityTestImplementation.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/base/BaseActivityTestImplementation.kt @@ -27,4 +27,4 @@ interface BaseActivityTestImplementation { val useIntents: Boolean get() = false -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/base/BaseTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/base/BaseTest.kt index f0512cb150..b2e4593c15 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/base/BaseTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/base/BaseTest.kt @@ -122,8 +122,8 @@ abstract class BaseTest : BaseActivityTestImplementation { */ protected fun isToastDisplayed(decorView: View?, message: String) { onView(withText(message)) - .inRoot(withDecorView(not(`is`(decorView)))) - .check(matches(isDisplayed())) + .inRoot(withDecorView(not(`is`(decorView)))) + .check(matches(isDisplayed())) } /** @@ -133,8 +133,8 @@ abstract class BaseTest : BaseActivityTestImplementation { */ protected fun isDialogWithTextDisplayed(decorView: View?, message: String) { onView(withText(message)) - .inRoot(withDecorView(not(`is`(decorView)))) - .check(matches(isDisplayed())) + .inRoot(withDecorView(not(`is`(decorView)))) + .check(matches(isDisplayed())) } /** @@ -143,15 +143,15 @@ abstract class BaseTest : BaseActivityTestImplementation { //todo-denbond7 - fix me protected fun testHelpScreen() { onView(withId(R.id.menuActionHelp)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(R.id.textViewAuthorHint)) - .check(matches(isDisplayed())) - .check(matches(withText(R.string.i_will_usually_reply_within_an_hour_except_when_i_sleep_tom))) + .check(matches(isDisplayed())) + .check(matches(withText(R.string.i_will_usually_reply_within_an_hour_except_when_i_sleep_tom))) onView(withText(R.string.help_feedback_or_question)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } /** @@ -163,8 +163,8 @@ abstract class BaseTest : BaseActivityTestImplementation { onView(withText(message)).check(matches(isDisplayed())) onView(withId(com.google.android.material.R.id.snackbar_action)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) } /** @@ -173,11 +173,11 @@ abstract class BaseTest : BaseActivityTestImplementation { protected fun checkIsSnackBarDisplayed(text: String? = null) { if (text.isNullOrEmpty()) { onView(withId(com.google.android.material.R.id.snackbar_action)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } else { onView(withId(com.google.android.material.R.id.snackbar_text)) - .check(matches(isDisplayed())) - .check(matches(withText(text))) + .check(matches(isDisplayed())) + .check(matches(withText(text))) } } @@ -186,7 +186,7 @@ abstract class BaseTest : BaseActivityTestImplementation { */ protected fun checkIsSnackBarNotDisplayed() { onView(withId(com.google.android.material.R.id.snackbar_action)) - .check(doesNotExist()) + .check(doesNotExist()) } /** @@ -198,14 +198,16 @@ abstract class BaseTest : BaseActivityTestImplementation { */ protected fun addTextToClipboard(label: String, text: String) { runOnUiThread { - val clipboard = getTargetContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + val clipboard = + getTargetContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val clip = ClipData.newPlainText(label, text) clipboard.setPrimaryClip(clip) } } protected fun checkClipboardText(text: CharSequence) { - val clipboardManager = getTargetContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + val clipboardManager = + getTargetContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val primaryClip: ClipData? = clipboardManager.primaryClip var clipboardText: CharSequence? = null @@ -239,14 +241,20 @@ abstract class BaseTest : BaseActivityTestImplementation { return InstrumentationRegistry.getInstrumentation().context } - fun getMsgInfo(path: String, mimeMsgPath: String, vararg atts: AttachmentInfo?): IncomingMessageInfo? { + fun getMsgInfo( + path: String, + mimeMsgPath: String, + vararg atts: AttachmentInfo? + ): IncomingMessageInfo? { val incomingMsgInfo = TestGeneralUtil.getObjectFromJson(path, IncomingMessageInfo::class.java) incomingMsgInfo?.msgEntity?.let { val uri = roomDatabase.msgDao().insert(it) val attEntities = mutableListOf() for (attInfo in atts) { - attInfo?.let { info -> AttachmentEntity.fromAttInfo(info)?.let { candidate -> attEntities.add(candidate) } } + attInfo?.let { info -> + AttachmentEntity.fromAttInfo(info)?.let { candidate -> attEntities.add(candidate) } + } } roomDatabase.attachmentDao().insert(attEntities) diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/database/MigrationTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/database/MigrationTest.kt index cfc38ac569..57a7a40167 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/database/MigrationTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/database/MigrationTest.kt @@ -40,9 +40,9 @@ class MigrationTest { @get:Rule val migrationTestHelper: MigrationTestHelper = MigrationTestHelper( - InstrumentationRegistry.getInstrumentation(), - FlowCryptRoomDatabase::class.java.canonicalName, - FrameworkSQLiteOpenHelperFactory() + InstrumentationRegistry.getInstrumentation(), + FlowCryptRoomDatabase::class.java.canonicalName, + FrameworkSQLiteOpenHelperFactory() ) @Test @@ -55,8 +55,8 @@ class MigrationTest { // Open latest version of the DB. Room will validate the schema once all migrations execute. Room.databaseBuilder( - InstrumentationRegistry.getInstrumentation().targetContext, - FlowCryptRoomDatabase::class.java, FlowCryptRoomDatabase.DB_NAME + InstrumentationRegistry.getInstrumentation().targetContext, + FlowCryptRoomDatabase::class.java, FlowCryptRoomDatabase.DB_NAME ).addMigrations(*arrayOfMigrations).build().apply { openHelper.writableDatabase close() @@ -66,4 +66,4 @@ class MigrationTest { companion object { const val INIT_DATABASE_VERSION = 19 } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/annotations/DebugTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/annotations/DebugTest.kt index 31a4bd19d5..9477ac0007 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/annotations/DebugTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/annotations/DebugTest.kt @@ -14,4 +14,4 @@ package com.flowcrypt.email.junit.annotations * E-mail: DenBond7@gmail.com */ @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) -annotation class DebugTest \ No newline at end of file +annotation class DebugTest diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/annotations/DependsOnMailServer.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/annotations/DependsOnMailServer.kt index d3579be111..89eb4c3670 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/annotations/DependsOnMailServer.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/annotations/DependsOnMailServer.kt @@ -15,4 +15,4 @@ package com.flowcrypt.email.junit.annotations * E-mail: DenBond7@gmail.com */ @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) -annotation class DependsOnMailServer \ No newline at end of file +annotation class DependsOnMailServer diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/annotations/NotReadyForCI.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/annotations/NotReadyForCI.kt index d71a92caf5..b00d54ad4a 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/annotations/NotReadyForCI.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/annotations/NotReadyForCI.kt @@ -15,4 +15,4 @@ package com.flowcrypt.email.junit.annotations * E-mail: DenBond7@gmail.com */ @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) -annotation class NotReadyForCI \ No newline at end of file +annotation class NotReadyForCI diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/DependsOnMailServerFilter.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/DependsOnMailServerFilter.kt index f9c2435253..a72df65f4d 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/DependsOnMailServerFilter.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/DependsOnMailServerFilter.kt @@ -23,4 +23,4 @@ class DependsOnMailServerFilter : ReadyForCIFilter() { } override fun describe() = "Filter tests that depend on an email server" -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/DoesNotNeedMailServerFilter.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/DoesNotNeedMailServerFilter.kt index 69b3621d2d..64eac7ef8a 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/DoesNotNeedMailServerFilter.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/DoesNotNeedMailServerFilter.kt @@ -23,4 +23,4 @@ class DoesNotNeedMailServerFilter : ReadyForCIFilter() { } override fun describe() = "Filter tests that don't need an email server" -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/NotReadyForCIFilter.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/NotReadyForCIFilter.kt index 13750cc661..257ea4a9b5 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/NotReadyForCIFilter.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/NotReadyForCIFilter.kt @@ -23,4 +23,4 @@ open class NotReadyForCIFilter : ParentFilter() { } override fun describe() = "Filter tests that can't be run on CI yet" -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/OtherTestsFilter.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/OtherTestsFilter.kt index de71070801..b0655c2db0 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/OtherTestsFilter.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/OtherTestsFilter.kt @@ -19,8 +19,10 @@ class OtherTestsFilter : ParentFilter() { private val doesNotNeedMailServerFilter = DoesNotNeedMailServerFilter() override fun evaluateTest(description: Description?): Boolean { - return (!dependsOnMailServerFilter.shouldRun(description) && !doesNotNeedMailServerFilter.shouldRun(description)) + return (!dependsOnMailServerFilter.shouldRun(description) && !doesNotNeedMailServerFilter.shouldRun( + description + )) } override fun describe() = "Filter tests that are not related to any conditions" -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/ReadyForCIFilter.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/ReadyForCIFilter.kt index a41085d5ed..a4c1bc8e71 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/ReadyForCIFilter.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/junit/filters/ReadyForCIFilter.kt @@ -18,8 +18,10 @@ import org.junit.runner.Description open class ReadyForCIFilter : ParentFilter() { override fun evaluateTest(description: Description?): Boolean { val annotationClass = NotReadyForCI::class.java - return (description?.testClass?.isAnnotationPresent(annotationClass) == false && description.getAnnotation(annotationClass) == null) + return (description?.testClass?.isAnnotationPresent(annotationClass) == false && description.getAnnotation( + annotationClass + ) == null) } override fun describe() = "Filter tests that are ready to be run on a CI server" -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/AppBarLayoutBackgroundColorMatcher.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/AppBarLayoutBackgroundColorMatcher.kt index 6f045a9e2b..fbe35583de 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/AppBarLayoutBackgroundColorMatcher.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/AppBarLayoutBackgroundColorMatcher.kt @@ -17,8 +17,8 @@ import org.hamcrest.Description * Time: 3:17 PM * E-mail: DenBond7@gmail.com */ -class AppBarLayoutBackgroundColorMatcher(val color: Int) - : BoundedMatcher(AppBarLayout::class.java) { +class AppBarLayoutBackgroundColorMatcher(val color: Int) : + BoundedMatcher(AppBarLayout::class.java) { public override fun matchesSafely(appBarLayout: AppBarLayout): Boolean { return if (appBarLayout.background is ColorDrawable) { color == (appBarLayout.background as ColorDrawable).color @@ -28,4 +28,4 @@ class AppBarLayoutBackgroundColorMatcher(val color: Int) override fun describeTo(description: Description) { description.appendText("Background color AppBarLayout: $color") } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/DrawableMatcher.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/DrawableMatcher.kt index acb40f1b0c..9800cf2c98 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/DrawableMatcher.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/DrawableMatcher.kt @@ -45,7 +45,8 @@ class DrawableMatcher(private val expectedId: Int) : TypeSafeMatcher(View: ANY -> return target.drawable != null else -> { val resources = target.getContext().resources - val expectedDrawable = resources.getDrawable(expectedId, target.getContext().theme) ?: return false + val expectedDrawable = + resources.getDrawable(expectedId, target.getContext().theme) ?: return false resourceName = resources.getResourceEntryName(expectedId) val bitmap = getBitmap(target.drawable) @@ -56,7 +57,11 @@ class DrawableMatcher(private val expectedId: Int) : TypeSafeMatcher(View: } private fun getBitmap(drawable: Drawable): Bitmap { - val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888) + val bitmap = Bitmap.createBitmap( + drawable.intrinsicWidth, + drawable.intrinsicHeight, + Bitmap.Config.ARGB_8888 + ) val canvas = Canvas(bitmap) drawable.setBounds(0, 0, canvas.width, canvas.height) drawable.draw(canvas) @@ -67,4 +72,4 @@ class DrawableMatcher(private val expectedId: Int) : TypeSafeMatcher(View: const val EMPTY = -1 const val ANY = -2 } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/EmptyListViewMather.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/EmptyListViewMather.kt index 9526a0e77a..f5d8b01445 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/EmptyListViewMather.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/EmptyListViewMather.kt @@ -28,4 +28,4 @@ class EmptyListViewMather : BaseMatcher() { override fun describeTo(description: Description) { description.appendText("List is not empty") } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/EmptyRecyclerViewMatcher.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/EmptyRecyclerViewMatcher.kt index e4a35c124a..8afccf5b86 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/EmptyRecyclerViewMatcher.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/EmptyRecyclerViewMatcher.kt @@ -28,4 +28,4 @@ class EmptyRecyclerViewMatcher : BaseMatcher() { override fun describeTo(description: Description) { description.appendText("RecyclerView is not empty") } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/ListViewItemCountMatcher.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/ListViewItemCountMatcher.kt index 850c646b4a..ec14e45ab0 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/ListViewItemCountMatcher.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/ListViewItemCountMatcher.kt @@ -35,4 +35,4 @@ class ListViewItemCountMatcher(val itemCount: Int) : BaseMatcher() override fun describeTo(description: Description) { description.appendText("The size of the list is not equal = $itemCount") } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/NachoTextViewChipBackgroundColorMatcher.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/NachoTextViewChipBackgroundColorMatcher.kt index 65003b15d1..55e8d3c52d 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/NachoTextViewChipBackgroundColorMatcher.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/NachoTextViewChipBackgroundColorMatcher.kt @@ -17,9 +17,10 @@ import org.hamcrest.Description * Time: 10:19 AM * E-mail: DenBond7@gmail.com */ -class NachoTextViewChipBackgroundColorMatcher(private val chipText: String, - private val backgroundColor: Int) - : BoundedMatcher(NachoTextView::class.java) { +class NachoTextViewChipBackgroundColorMatcher( + private val chipText: String, + private val backgroundColor: Int +) : BoundedMatcher(NachoTextView::class.java) { public override fun matchesSafely(nachoTextView: NachoTextView): Boolean { val expectedChip = nachoTextView.allChips.firstOrNull { it.text == chipText } ?: return false val pgpContactChipSpan = expectedChip as? PGPContactChipSpan ?: return false @@ -29,4 +30,4 @@ class NachoTextViewChipBackgroundColorMatcher(private val chipText: String, override fun describeTo(description: Description) { description.appendText("Chip details: text = $chipText, color = $backgroundColor") } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/RecyclerViewItemCountMatcher.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/RecyclerViewItemCountMatcher.kt index 8495ca43f7..f0a253689e 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/RecyclerViewItemCountMatcher.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/RecyclerViewItemCountMatcher.kt @@ -28,4 +28,4 @@ class RecyclerViewItemCountMatcher(private val itemCount: Int) : BaseM override fun describeTo(description: Description) { description.appendText("The count of the RecyclerView is not equal = $itemCount") } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/SecurityTypeOptionMatcher.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/SecurityTypeOptionMatcher.kt index 7c864223af..dabb3a754e 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/SecurityTypeOptionMatcher.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/matchers/SecurityTypeOptionMatcher.kt @@ -15,7 +15,8 @@ import org.hamcrest.Description * Time: 3:08 PM * E-mail: DenBond7@gmail.com */ -class SecurityTypeOptionMatcher(val option: SecurityType.Option) : BaseMatcher() { +class SecurityTypeOptionMatcher(val option: SecurityType.Option) : + BaseMatcher() { override fun describeTo(description: Description?) { description?.appendText("The input option = $option") } @@ -27,4 +28,4 @@ class SecurityTypeOptionMatcher(val option: SecurityType.Option) : BaseMatcher) - : BoundedMatcher(Toolbar::class.java) { +class ToolBarTitleMatcher(private val textMatcher: Matcher) : + BoundedMatcher(Toolbar::class.java) { override fun matchesSafely(toolbar: Toolbar): Boolean { return textMatcher.matches(toolbar.title) diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddAccountAliasToDatabaseRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddAccountAliasToDatabaseRule.kt index 4b171972c8..33f5e5efc6 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddAccountAliasToDatabaseRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddAccountAliasToDatabaseRule.kt @@ -30,4 +30,4 @@ class AddAccountAliasToDatabaseRule constructor(val alias: AccountAliasesEntity) private fun saveAliasToDatabase() { FlowCryptRoomDatabase.getDatabase(targetContext).accountAliasesDao().insert(alias) } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddAccountToDatabaseRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddAccountToDatabaseRule.kt index c84d7a9f94..5b93812c0a 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddAccountToDatabaseRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddAccountToDatabaseRule.kt @@ -33,4 +33,4 @@ class AddAccountToDatabaseRule constructor(val account: AccountEntity) : BaseRul private fun saveAccountToDatabase() { FlowCryptRoomDatabase.getDatabase(targetContext).accountDao().addAccount(account) } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddAccountWithAliasesDatabaseRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddAccountWithAliasesDatabaseRule.kt index c98a93881a..3d1a99e769 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddAccountWithAliasesDatabaseRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddAccountWithAliasesDatabaseRule.kt @@ -17,9 +17,11 @@ import org.junit.runners.model.Statement * Time: 1:03 PM * E-mail: DenBond7@gmail.com */ -class AddAccountWithAliasesDatabaseRule constructor(val accountEntity: AccountEntity, - val accountAliasesEntity: AccountAliasesEntity) : - BaseRule() { +class AddAccountWithAliasesDatabaseRule constructor( + val accountEntity: AccountEntity, + val accountAliasesEntity: AccountAliasesEntity +) : + BaseRule() { override fun apply(base: Statement, description: Description): Statement { return object : Statement() { @@ -35,4 +37,4 @@ class AddAccountWithAliasesDatabaseRule constructor(val accountEntity: AccountEn roomDatabase.accountDao().insert(accountEntity) roomDatabase.accountAliasesDao().insert(accountAliasesEntity) } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddContactsToDatabaseRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddContactsToDatabaseRule.kt index c8221c5040..03b34cbee4 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddContactsToDatabaseRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddContactsToDatabaseRule.kt @@ -25,7 +25,7 @@ class AddContactsToDatabaseRule(val pgpContacts: List) : BaseRule() return object : Statement() { override fun evaluate() { FlowCryptRoomDatabase.getDatabase(targetContext).contactsDao().insert( - pgpContacts.map { it.toContactEntity() }) + pgpContacts.map { it.toContactEntity() }) base.evaluate() } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddLabelsToDatabaseRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddLabelsToDatabaseRule.kt index c578994318..2ea3721d0a 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddLabelsToDatabaseRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddLabelsToDatabaseRule.kt @@ -18,7 +18,10 @@ import org.junit.runners.model.Statement * Time: 09:19 * E-mail: DenBond7@gmail.com */ -class AddLabelsToDatabaseRule(private val account: AccountEntity, private val folders: List) : BaseRule() { +class AddLabelsToDatabaseRule( + private val account: AccountEntity, + private val folders: List +) : BaseRule() { override fun apply(base: Statement, description: Description): Statement { return object : Statement() { @@ -38,4 +41,3 @@ class AddLabelsToDatabaseRule(private val account: AccountEntity, private val fo FlowCryptRoomDatabase.getDatabase(targetContext).labelDao().insert(labels) } } - diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddMessageToDatabaseRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddMessageToDatabaseRule.kt index fbcdf75a20..4d6121c166 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddMessageToDatabaseRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddMessageToDatabaseRule.kt @@ -27,12 +27,17 @@ import javax.mail.UIDFolder * Time: 09:48 * E-mail: DenBond7@gmail.com */ -class AddMessageToDatabaseRule(val account: AccountEntity, val localFolder: LocalFolder) : BaseRule() { +class AddMessageToDatabaseRule(val account: AccountEntity, val localFolder: LocalFolder) : + BaseRule() { private var message: Message? = null init { try { - OpenStoreHelper.openStore(targetContext, account, OpenStoreHelper.getAccountSess(targetContext, account)).use { store -> + OpenStoreHelper.openStore( + targetContext, + account, + OpenStoreHelper.getAccountSess(targetContext, account) + ).use { store -> store.getFolder(localFolder.fullName).use { folder -> val imapFolder = (folder as IMAPFolder).apply { open(Folder.READ_ONLY) } val messages = arrayOf(imapFolder.getMessage(imapFolder.messageCount)) @@ -69,11 +74,11 @@ class AddMessageToDatabaseRule(val account: AccountEntity, val localFolder: Loca private fun saveMsgToDatabase() { message?.let { val msgEntity = MessageEntity.genMsgEntity( - email = account.email, - label = localFolder.fullName, - msg = it, - uid = 0, - isNew = false + email = account.email, + label = localFolder.fullName, + msg = it, + uid = 0, + isNew = false ) FlowCryptRoomDatabase.getDatabase(targetContext).msgDao().insert(msgEntity) diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddPrivateKeyToDatabaseRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddPrivateKeyToDatabaseRule.kt index 3c32ff7d7f..aa95e62f49 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddPrivateKeyToDatabaseRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddPrivateKeyToDatabaseRule.kt @@ -21,16 +21,20 @@ import org.junit.runners.model.Statement * Time: 17:54 * E-mail: DenBond7@gmail.com */ -class AddPrivateKeyToDatabaseRule(val accountEntity: AccountEntity, - val keyPath: String, - val passphrase: String, - val sourceType: KeyImportDetails.SourceType) : BaseRule() { +class AddPrivateKeyToDatabaseRule( + val accountEntity: AccountEntity, + val keyPath: String, + val passphrase: String, + val sourceType: KeyImportDetails.SourceType +) : BaseRule() { lateinit var pgpKeyDetails: PgpKeyDetails private set - constructor() : this(AccountDaoManager.getDefaultAccountDao(), "pgp/default@flowcrypt.test_fisrtKey_prv_strong.asc", - TestConstants.DEFAULT_STRONG_PASSWORD, KeyImportDetails.SourceType.EMAIL) + constructor() : this( + AccountDaoManager.getDefaultAccountDao(), "pgp/default@flowcrypt.test_fisrtKey_prv_strong.asc", + TestConstants.DEFAULT_STRONG_PASSWORD, KeyImportDetails.SourceType.EMAIL + ) override fun apply(base: Statement, description: Description): Statement { return object : Statement() { diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/BaseRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/BaseRule.kt index cafa4f994a..c8f4896576 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/BaseRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/BaseRule.kt @@ -18,4 +18,4 @@ import org.junit.rules.TestRule abstract class BaseRule : TestRule { protected val context: Context = InstrumentationRegistry.getInstrumentation().context protected val targetContext: Context = InstrumentationRegistry.getInstrumentation().targetContext -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/CustomScreenCaptureProcessor.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/CustomScreenCaptureProcessor.kt index f8674d5249..d5e9c18e73 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/CustomScreenCaptureProcessor.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/CustomScreenCaptureProcessor.kt @@ -15,7 +15,7 @@ import androidx.test.runner.screenshot.BasicScreenCaptureProcessor import androidx.test.runner.screenshot.ScreenCapture import org.apache.commons.io.FilenameUtils import java.io.BufferedOutputStream -import java.util.* +import java.util.Locale /** * @author Denis Bondarenko @@ -43,8 +43,10 @@ class CustomScreenCaptureProcessor : BasicScreenCaptureProcessor() { put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/screenshots") } - val imageUri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, - contentValues) ?: return "" + val imageUri = contentResolver.insert( + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + contentValues + ) ?: return "" val outputStream = contentResolver.openOutputStream(imageUri) ?: return "" BufferedOutputStream(outputStream).use { out -> capture.bitmap.compress(capture.format, 100, out) @@ -56,4 +58,4 @@ class CustomScreenCaptureProcessor : BasicScreenCaptureProcessor() { return "" } } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/FlowCryptMockWebServerRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/FlowCryptMockWebServerRule.kt index 3fe040842e..122834b9e0 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/FlowCryptMockWebServerRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/FlowCryptMockWebServerRule.kt @@ -50,12 +50,14 @@ class FlowCryptMockWebServerRule(val port: Int, val responseDispatcher: Dispatch * https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/HttpsServer.java */ private fun getSSLSocketFactory(): SSLSocketFactory { - val serverCertificate: HeldCertificate = HeldCertificate.decode(TestGeneralUtil - .readResourcesAsString("ssl/server_combined.pem")) + val serverCertificate: HeldCertificate = HeldCertificate.decode( + TestGeneralUtil + .readResourcesAsString("ssl/server_combined.pem") + ) val serverHandshakeCertificates: HandshakeCertificates = HandshakeCertificates.Builder() - .heldCertificate(serverCertificate) - .build() + .heldCertificate(serverCertificate) + .build() return serverHandshakeCertificates.sslSocketFactory() } @@ -76,24 +78,24 @@ class FlowCryptMockWebServerRule(val port: Int, val responseDispatcher: Dispatch */ private fun genSSLSocketFactory(): SSLSocketFactory { val rootCertificate: HeldCertificate = HeldCertificate.Builder() - .certificateAuthority(1) - .build() + .certificateAuthority(1) + .build() val intermediateCertificate: HeldCertificate = HeldCertificate.Builder() - .certificateAuthority(0) - .signedBy(rootCertificate) - .build() + .certificateAuthority(0) + .signedBy(rootCertificate) + .build() val localhost: String = InetAddress.getByName("localhost").canonicalHostName val serverCertificate: HeldCertificate = HeldCertificate.Builder() - .addSubjectAlternativeName(localhost) - .signedBy(intermediateCertificate) - .build() + .addSubjectAlternativeName(localhost) + .signedBy(intermediateCertificate) + .build() val serverHandshakeCertificates: HandshakeCertificates = HandshakeCertificates.Builder() - .heldCertificate(serverCertificate) - .build() + .heldCertificate(serverCertificate) + .build() return serverHandshakeCertificates.sslSocketFactory() } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/LazyActivityScenarioRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/LazyActivityScenarioRule.kt index 5d36ae5ba9..b6a6a30767 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/LazyActivityScenarioRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/LazyActivityScenarioRule.kt @@ -67,11 +67,17 @@ class LazyActivityScenarioRule : ExternalResource { fun getNonNullScenario(): ActivityScenario = checkNotNull(scenario) } -inline fun lazyActivityScenarioRule(launchActivity: Boolean = true, noinline intentSupplier: () -> Intent): LazyActivityScenarioRule = - LazyActivityScenarioRule(launchActivity, intentSupplier) - -inline fun lazyActivityScenarioRule(launchActivity: Boolean = true, intent: Intent? = null): LazyActivityScenarioRule = if (intent == null) { +inline fun lazyActivityScenarioRule( + launchActivity: Boolean = true, + noinline intentSupplier: () -> Intent +): LazyActivityScenarioRule = + LazyActivityScenarioRule(launchActivity, intentSupplier) + +inline fun lazyActivityScenarioRule( + launchActivity: Boolean = true, + intent: Intent? = null +): LazyActivityScenarioRule = if (intent == null) { LazyActivityScenarioRule(launchActivity, A::class.java) } else { LazyActivityScenarioRule(launchActivity, intent) -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/Repeat.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/Repeat.kt index 84e6e52c76..8b74c3431a 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/Repeat.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/Repeat.kt @@ -12,6 +12,8 @@ package com.flowcrypt.email.rules * E-mail: DenBond7@gmail.com */ @Retention() -@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, - AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.ANNOTATION_CLASS) +@Target( + AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.ANNOTATION_CLASS +) annotation class Repeat(val value: Int = 1) diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RepeatRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RepeatRule.kt index c89ae29c23..1cc69a79c6 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RepeatRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RepeatRule.kt @@ -35,4 +35,4 @@ class RepeatRule(private val retryCount: Int = 3) : BaseRule() { } } } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RepeatedRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RepeatedRule.kt index 20d28edbe5..b3f85454bd 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RepeatedRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RepeatedRule.kt @@ -27,8 +27,10 @@ class RepeatedRule : BaseRule() { return result } - private class RepeatStatement internal constructor(private val statement: Statement, private val repeat: Int) - : Statement() { + private class RepeatStatement( + private val statement: Statement, + private val repeat: Int + ) : Statement() { override fun evaluate() { for (i in 0 until repeat) { diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RetryOnFailure.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RetryOnFailure.kt index 57403d02d6..2cf65ea894 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RetryOnFailure.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RetryOnFailure.kt @@ -14,8 +14,9 @@ package com.flowcrypt.email.rules * E-mail: DenBond7@gmail.com */ @Target( - AnnotationTarget.FUNCTION, - AnnotationTarget.PROPERTY_GETTER, - AnnotationTarget.PROPERTY_SETTER, - AnnotationTarget.ANNOTATION_CLASS) + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.ANNOTATION_CLASS +) annotation class RetryOnFailure(val value: Int = 0) diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RetryRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RetryRule.kt index dc5d36318c..324203de5a 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RetryRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/RetryRule.kt @@ -28,10 +28,10 @@ class RetryRule(private val retryCount: Int = 0) : BaseRule() { return object : Statement() { override fun evaluate() { val fromAnnotation = description - .annotations - .filterIsInstance() - .firstOrNull() - ?.value + .annotations + .filterIsInstance() + .firstOrNull() + ?.value val attempts = if (fromAnnotation == null || fromAnnotation !in 1..MAX_RETRY_VALUE) { if (retryCount in 1..MAX_RETRY_VALUE) retryCount else 1 @@ -42,11 +42,11 @@ class RetryRule(private val retryCount: Int = 0) : BaseRule() { var caughtThrowable: Throwable? = null repeat(attempts) { times -> runCatching { base.evaluate() } - .onSuccess { return } - .onFailure { - caughtThrowable = it - System.err.println(description.displayName.toString() + ": run $times failed") - } + .onSuccess { return } + .onFailure { + caughtThrowable = it + System.err.println(description.displayName.toString() + ": run $times failed") + } } System.err.println(description.displayName.toString() + ": giving up after " + attempts + " failures") caughtThrowable?.let { throw it } ?: throw RuntimeException("Something went wrong") @@ -59,4 +59,4 @@ class RetryRule(private val retryCount: Int = 0) : BaseRule() { private const val MAX_RETRY_VALUE = 100 val DEFAULT = RetryRule(DEFAULT_RETRY_VALUE) } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/ScreenshotTestRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/ScreenshotTestRule.kt index 676d1fdd7c..bddf98c243 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/ScreenshotTestRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/ScreenshotTestRule.kt @@ -36,4 +36,4 @@ class ScreenshotTestRule : TestWatcher() { e.printStackTrace() } } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/security/KeyStoreCryptoManagerTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/security/KeyStoreCryptoManagerTest.kt index 01e47ce0c0..cf5f5614e6 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/security/KeyStoreCryptoManagerTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/security/KeyStoreCryptoManagerTest.kt @@ -23,7 +23,7 @@ import org.junit.runner.RunWith import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.nio.charset.StandardCharsets -import java.util.* +import java.util.Properties import javax.crypto.CipherInputStream import javax.crypto.CipherOutputStream import javax.mail.Session @@ -38,9 +38,12 @@ import javax.mail.internet.MimeMessage @SmallTest @RunWith(AndroidJUnit4::class) class KeyStoreCryptoManagerTest { - private val originalData = IOUtils.toString(InstrumentationRegistry + private val originalData = IOUtils.toString( + InstrumentationRegistry .getInstrumentation().context.assets.open( - "messages/mime/standard_msg_info_plaintext.txt"), StandardCharsets.UTF_8) + "messages/mime/standard_msg_info_plaintext.txt" + ), StandardCharsets.UTF_8 + ) @Before fun setUp() { @@ -61,19 +64,28 @@ class KeyStoreCryptoManagerTest { @Test fun testDataAsStream() { - val msg = MimeMessage(Session.getInstance(Properties()), - InstrumentationRegistry.getInstrumentation().context.assets.open( - "messages/mime/standard_msg_info_plaintext.txt")) + val msg = MimeMessage( + Session.getInstance(Properties()), + InstrumentationRegistry.getInstrumentation().context.assets.open( + "messages/mime/standard_msg_info_plaintext.txt" + ) + ) val cipherForEncryption = KeyStoreCryptoManager.getCipherForEncryption() val byteArrayOutputStream = ByteArrayOutputStream() - val base64OutputStream = Base64OutputStream(byteArrayOutputStream, - KeyStoreCryptoManager.BASE64_FLAGS) + val base64OutputStream = Base64OutputStream( + byteArrayOutputStream, + KeyStoreCryptoManager.BASE64_FLAGS + ) val outputStream = CipherOutputStream(base64OutputStream, cipherForEncryption) outputStream.use { - byteArrayOutputStream.write(Base64.encodeToString(cipherForEncryption.iv, - KeyStoreCryptoManager.BASE64_FLAGS).toByteArray()) + byteArrayOutputStream.write( + Base64.encodeToString( + cipherForEncryption.iv, + KeyStoreCryptoManager.BASE64_FLAGS + ).toByteArray() + ) byteArrayOutputStream.write("\n".toByteArray()) msg.writeTo(outputStream) @@ -81,10 +93,13 @@ class KeyStoreCryptoManagerTest { } val cipherForDecryption = KeyStoreCryptoManager.getCipherForDecryption( - Base64.encodeToString(cipherForEncryption.iv, KeyStoreCryptoManager.BASE64_FLAGS)) + Base64.encodeToString(cipherForEncryption.iv, KeyStoreCryptoManager.BASE64_FLAGS) + ) val byteArrayInputStream = ByteArrayInputStream(byteArrayOutputStream.toByteArray()) - val base64InputStream = Base64InputStream(byteArrayInputStream, - KeyStoreCryptoManager.BASE64_FLAGS) + val base64InputStream = Base64InputStream( + byteArrayInputStream, + KeyStoreCryptoManager.BASE64_FLAGS + ) val inputStream = CipherInputStream(base64InputStream, cipherForDecryption) val outputStreamFoResult = ByteArrayOutputStream() @@ -100,29 +115,40 @@ class KeyStoreCryptoManagerTest { inputStream.copyTo(outputStreamFoResult) val decodedDataAsString = String(outputStreamFoResult.toByteArray()) - assertTrue(originalData.replace("\r\n".toRegex(), "\n") == - decodedDataAsString.replace("\r\n".toRegex(), "\n")) + assertTrue( + originalData.replace("\r\n".toRegex(), "\n") == + decodedDataAsString.replace("\r\n".toRegex(), "\n") + ) } @Test fun testDataAsStreamFromCacheManager() { - val msg = MimeMessage(Session.getInstance(Properties()), - InstrumentationRegistry.getInstrumentation().context.assets.open( - "messages/mime/standard_msg_info_plaintext.txt")) + val msg = MimeMessage( + Session.getInstance(Properties()), + InstrumentationRegistry.getInstrumentation().context.assets.open( + "messages/mime/standard_msg_info_plaintext.txt" + ) + ) val key = "temp" val editor = MsgsCacheManager.diskLruCache.edit(key) ?: return val bufferedSink = editor.newSink(0).buffer() val outputStreamOfBufferedSink = bufferedSink.outputStream() val cipherForEncryption = KeyStoreCryptoManager.getCipherForEncryption() - val base64OutputStream = Base64OutputStream(outputStreamOfBufferedSink, - KeyStoreCryptoManager.BASE64_FLAGS) + val base64OutputStream = Base64OutputStream( + outputStreamOfBufferedSink, + KeyStoreCryptoManager.BASE64_FLAGS + ) val outputStream = CipherOutputStream(base64OutputStream, cipherForEncryption) try { outputStream.use { - outputStreamOfBufferedSink.write(Base64.encodeToString(cipherForEncryption.iv, - KeyStoreCryptoManager.BASE64_FLAGS).toByteArray()) + outputStreamOfBufferedSink.write( + Base64.encodeToString( + cipherForEncryption.iv, + KeyStoreCryptoManager.BASE64_FLAGS + ).toByteArray() + ) outputStreamOfBufferedSink.write("\n".toByteArray()) msg.writeTo(it) bufferedSink.flush() @@ -135,14 +161,19 @@ class KeyStoreCryptoManagerTest { val snapshot = MsgsCacheManager.getMsgSnapshot(key) ?: throw IllegalArgumentException() val inputStreamFromUri = InstrumentationRegistry.getInstrumentation() - .targetContext?.contentResolver?.openInputStream(snapshot.getUri(0) - ?: throw NullPointerException()) ?: throw java.lang.NullPointerException() + .targetContext?.contentResolver?.openInputStream( + snapshot.getUri(0) + ?: throw NullPointerException() + ) ?: throw java.lang.NullPointerException() val cipherForDecryption = KeyStoreCryptoManager.getCipherForDecryption( - Base64.encodeToString(cipherForEncryption.iv, KeyStoreCryptoManager.BASE64_FLAGS)) + Base64.encodeToString(cipherForEncryption.iv, KeyStoreCryptoManager.BASE64_FLAGS) + ) val byteArrayInputStream = ByteArrayInputStream(inputStreamFromUri.readBytes()) - val base64InputStream = Base64InputStream(byteArrayInputStream, - KeyStoreCryptoManager.BASE64_FLAGS) + val base64InputStream = Base64InputStream( + byteArrayInputStream, + KeyStoreCryptoManager.BASE64_FLAGS + ) val inputStream = CipherInputStream(base64InputStream, cipherForDecryption) val outputStreamFoResult = ByteArrayOutputStream() @@ -158,7 +189,9 @@ class KeyStoreCryptoManagerTest { inputStream.copyTo(outputStreamFoResult) val decodedDataAsString = String(outputStreamFoResult.toByteArray()) - assertTrue(originalData.replace("\r\n".toRegex(), "\n") == - decodedDataAsString.replace("\r\n".toRegex(), "\n")) + assertTrue( + originalData.replace("\r\n".toRegex(), "\n") == + decodedDataAsString.replace("\r\n".toRegex(), "\n") + ) } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/AddOtherAccountFragmentTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/AddOtherAccountFragmentTest.kt index a2a7c12dd2..8b56aea1d2 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/AddOtherAccountFragmentTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/AddOtherAccountFragmentTest.kt @@ -80,23 +80,23 @@ class AddOtherAccountFragmentTest : BaseTest() { @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) private val authCreds: AuthCredentials = AuthCredentialsManager.getLocalWithOneBackupAuthCreds() @Before fun openAddOtherAccountFragment() { onView(withId(R.id.buttonOtherEmailProvider)) - .perform(click()) + .perform(click()) } @Test fun testShowSnackBarIfFieldEmpty() { onView(withId(R.id.checkBoxAdvancedMode)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) clearAllFields() @@ -107,12 +107,12 @@ class AddOtherAccountFragmentTest : BaseTest() { checkIsFieldEmptyWork(R.id.editTextImapServer, R.string.imap_server) checkIsFieldEmptyWork(R.id.editTextImapPort, R.string.imap_port) onView(withId(R.id.editTextImapPort)) - .perform(scrollTo(), typeText(authCreds.imapPort.toString())) + .perform(scrollTo(), typeText(authCreds.imapPort.toString())) checkIsFieldEmptyWork(R.id.editTextSmtpServer, R.string.smtp_server) checkIsFieldEmptyWork(R.id.editTextSmtpPort, R.string.smtp_port) onView(withId(R.id.editTextSmtpPort)) - .perform(scrollTo(), typeText(authCreds.smtpPort.toString())) + .perform(scrollTo(), typeText(authCreds.smtpPort.toString())) checkIsFieldEmptyWork(R.id.editTextSmtpUsername, R.string.smtp_username) checkIsFieldEmptyWork(R.id.editTextSmtpPassword, R.string.smtp_password) @@ -121,34 +121,46 @@ class AddOtherAccountFragmentTest : BaseTest() { @Test fun testIsPasswordFieldsAlwaysEmptyAtStart() { onView(withId(R.id.editTextPassword)) - .check(matches(withText(isEmptyString()))) + .check(matches(withText(isEmptyString()))) enableAdvancedMode() onView(withId(R.id.checkBoxRequireSignInForSmtp)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) onView(withId(R.id.editTextSmtpPassword)) - .check(matches(withText(isEmptyString()))) + .check(matches(withText(isEmptyString()))) } @Test fun testChangingImapPortWhenSelectSpinnerItem() { enableAdvancedMode() - checkSecurityTypeOpt(R.id.editTextImapPort, R.id.spinnerImapSecurityType, - SecurityType.Option.STARTLS, JavaEmailConstants.DEFAULT_IMAP_PORT.toString()) - checkSecurityTypeOpt(R.id.editTextImapPort, R.id.spinnerImapSecurityType, - SecurityType.Option.SSL_TLS, JavaEmailConstants.SSL_IMAP_PORT.toString()) - checkSecurityTypeOpt(R.id.editTextImapPort, R.id.spinnerImapSecurityType, - SecurityType.Option.NONE, JavaEmailConstants.DEFAULT_IMAP_PORT.toString()) + checkSecurityTypeOpt( + R.id.editTextImapPort, R.id.spinnerImapSecurityType, + SecurityType.Option.STARTLS, JavaEmailConstants.DEFAULT_IMAP_PORT.toString() + ) + checkSecurityTypeOpt( + R.id.editTextImapPort, R.id.spinnerImapSecurityType, + SecurityType.Option.SSL_TLS, JavaEmailConstants.SSL_IMAP_PORT.toString() + ) + checkSecurityTypeOpt( + R.id.editTextImapPort, R.id.spinnerImapSecurityType, + SecurityType.Option.NONE, JavaEmailConstants.DEFAULT_IMAP_PORT.toString() + ) } @Test fun testChangingSmtpPortWhenSelectSpinnerItem() { enableAdvancedMode() - checkSecurityTypeOpt(R.id.editTextSmtpPort, R.id.spinnerSmtpSecyrityType, - SecurityType.Option.STARTLS, JavaEmailConstants.STARTTLS_SMTP_PORT.toString()) - checkSecurityTypeOpt(R.id.editTextSmtpPort, R.id.spinnerSmtpSecyrityType, - SecurityType.Option.SSL_TLS, JavaEmailConstants.SSL_SMTP_PORT.toString()) - checkSecurityTypeOpt(R.id.editTextSmtpPort, R.id.spinnerSmtpSecyrityType, - SecurityType.Option.NONE, JavaEmailConstants.DEFAULT_SMTP_PORT.toString()) + checkSecurityTypeOpt( + R.id.editTextSmtpPort, R.id.spinnerSmtpSecyrityType, + SecurityType.Option.STARTLS, JavaEmailConstants.STARTTLS_SMTP_PORT.toString() + ) + checkSecurityTypeOpt( + R.id.editTextSmtpPort, R.id.spinnerSmtpSecyrityType, + SecurityType.Option.SSL_TLS, JavaEmailConstants.SSL_SMTP_PORT.toString() + ) + checkSecurityTypeOpt( + R.id.editTextSmtpPort, R.id.spinnerSmtpSecyrityType, + SecurityType.Option.NONE, JavaEmailConstants.DEFAULT_SMTP_PORT.toString() + ) } @Test @@ -157,40 +169,40 @@ class AddOtherAccountFragmentTest : BaseTest() { enableAdvancedMode() onView(withId(R.id.editTextEmail)) - .perform(clearText(), typeText(authCreds.email), closeSoftKeyboard()) + .perform(clearText(), typeText(authCreds.email), closeSoftKeyboard()) onView(withId(R.id.editTextUserName)) - .perform(clearText(), typeText(authCreds.username), closeSoftKeyboard()) + .perform(clearText(), typeText(authCreds.username), closeSoftKeyboard()) onView(withId(R.id.editTextImapServer)) - .perform(clearText(), typeText(authCreds.imapServer), closeSoftKeyboard()) + .perform(clearText(), typeText(authCreds.imapServer), closeSoftKeyboard()) onView(withId(R.id.editTextSmtpServer)) - .perform(clearText(), typeText(authCreds.smtpServer), closeSoftKeyboard()) + .perform(clearText(), typeText(authCreds.smtpServer), closeSoftKeyboard()) val newUserName = "test" val newHost = "test.com" val fullUserName = newUserName + TestConstants.COMMERCIAL_AT_SYMBOL + newHost onView(withId(R.id.editTextEmail)) - .perform(scrollTo(), clearText(), typeText(fullUserName), closeSoftKeyboard()) + .perform(scrollTo(), clearText(), typeText(fullUserName), closeSoftKeyboard()) onView(withId(R.id.editTextUserName)) - .perform(scrollTo()) - .check(matches(not(withText(authCreds.username)))) + .perform(scrollTo()) + .check(matches(not(withText(authCreds.username)))) onView(withId(R.id.editTextUserName)) - .check(matches(withText(fullUserName))) + .check(matches(withText(fullUserName))) onView(withId(R.id.editTextImapServer)) - .perform(scrollTo()) - .check(matches(not(withText(authCreds.imapServer)))) + .perform(scrollTo()) + .check(matches(not(withText(authCreds.imapServer)))) onView(withId(R.id.editTextImapServer)) - .check(matches(withText(IMAP_SERVER_PREFIX + newHost))) + .check(matches(withText(IMAP_SERVER_PREFIX + newHost))) onView(withId(R.id.editTextSmtpServer)) - .perform(scrollTo()) - .check(matches(not(withText(authCreds.smtpServer)))) + .perform(scrollTo()) + .check(matches(not(withText(authCreds.smtpServer)))) onView(withId(R.id.editTextSmtpServer)) - .check(matches(withText(SMTP_SERVER_PREFIX + newHost))) + .check(matches(withText(SMTP_SERVER_PREFIX + newHost))) onView(withId(R.id.checkBoxRequireSignInForSmtp)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) onView(withId(R.id.editTextSmtpUsername)) - .perform(scrollTo()) - .check(matches(withText(fullUserName))) + .perform(scrollTo()) + .check(matches(withText(fullUserName))) } @Test @@ -198,58 +210,61 @@ class AddOtherAccountFragmentTest : BaseTest() { enableAdvancedMode() onView(withId(R.id.checkBoxRequireSignInForSmtp)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) onView(withId(R.id.editTextSmtpUsername)) - .perform(scrollTo()) - .check(matches(isDisplayed())) + .perform(scrollTo()) + .check(matches(isDisplayed())) onView(withId(R.id.editTextSmtpPassword)) - .perform(scrollTo()) - .check(matches(isDisplayed())).check(matches(withText(isEmptyString()))) + .perform(scrollTo()) + .check(matches(isDisplayed())).check(matches(withText(isEmptyString()))) onView(withId(R.id.checkBoxRequireSignInForSmtp)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) onView(withId(R.id.editTextSmtpUsername)) - .check(matches(not(isDisplayed()))) + .check(matches(not(isDisplayed()))) onView(withId(R.id.editTextSmtpPassword)) - .check(matches(not(isDisplayed()))) + .check(matches(not(isDisplayed()))) } @Test fun testFieldsAutoFilling() { enableAdvancedMode() - val userName = authCreds.email.substring(0, authCreds.email.indexOf(TestConstants.COMMERCIAL_AT_SYMBOL)) - val host = authCreds.email.substring(authCreds.email.indexOf(TestConstants.COMMERCIAL_AT_SYMBOL) + 1) + val userName = + authCreds.email.substring(0, authCreds.email.indexOf(TestConstants.COMMERCIAL_AT_SYMBOL)) + val host = + authCreds.email.substring(authCreds.email.indexOf(TestConstants.COMMERCIAL_AT_SYMBOL) + 1) - val incorrectEmailAddresses = arrayOf("default", "default@", "default@denbond7", "default@denbond7.") + val incorrectEmailAddresses = + arrayOf("default", "default@", "default@denbond7", "default@denbond7.") for (invalidEmailAddress in incorrectEmailAddresses) { onView(withId(R.id.editTextEmail)) - .perform(scrollTo(), clearText(), typeText(invalidEmailAddress), closeSoftKeyboard()) + .perform(scrollTo(), clearText(), typeText(invalidEmailAddress), closeSoftKeyboard()) onView(withId(R.id.editTextUserName)) - .perform(scrollTo()) - .check(matches(withText(isEmptyString()))) + .perform(scrollTo()) + .check(matches(withText(isEmptyString()))) onView(withId(R.id.editTextImapServer)) - .perform(scrollTo()) - .check(matches(withText(isEmptyString()))) + .perform(scrollTo()) + .check(matches(withText(isEmptyString()))) onView(withId(R.id.editTextSmtpServer)) - .perform(scrollTo()) - .check(matches(withText(isEmptyString()))) + .perform(scrollTo()) + .check(matches(withText(isEmptyString()))) } val text = userName + TestConstants.COMMERCIAL_AT_SYMBOL + host onView(withId(R.id.editTextEmail)) - .perform(scrollTo(), clearText(), typeText(text), closeSoftKeyboard()) + .perform(scrollTo(), clearText(), typeText(text), closeSoftKeyboard()) onView(withId(R.id.editTextUserName)) - .perform(scrollTo()) - .check(matches(withText(text))) + .perform(scrollTo()) + .check(matches(withText(text))) onView(withId(R.id.editTextImapServer)) - .perform(scrollTo()) - .check(matches(withText(IMAP_SERVER_PREFIX + host))) + .perform(scrollTo()) + .check(matches(withText(IMAP_SERVER_PREFIX + host))) onView(withId(R.id.editTextSmtpServer)) - .perform(scrollTo()) - .check(matches(withText(SMTP_SERVER_PREFIX + host))) + .perform(scrollTo()) + .check(matches(withText(SMTP_SERVER_PREFIX + host))) } @Test @@ -258,18 +273,19 @@ class AddOtherAccountFragmentTest : BaseTest() { enableAdvancedMode() fillAllFields(authCreds) - val invalidEmailAddresses = arrayOf("default", "default@", "default@@flowcrypt.test", "@flowcrypt.test", " ") + val invalidEmailAddresses = + arrayOf("default", "default@", "default@@flowcrypt.test", "@flowcrypt.test", " ") for (invalidEmailAddress in invalidEmailAddresses) { onView(withId(R.id.editTextEmail)) - .perform(scrollTo(), clearText(), typeText(invalidEmailAddress), closeSoftKeyboard()) + .perform(scrollTo(), clearText(), typeText(invalidEmailAddress), closeSoftKeyboard()) onView(withId(R.id.buttonTryToConnect)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) onView(withText(getResString(R.string.error_email_is_not_valid))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(com.google.android.material.R.id.snackbar_action)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) } } @@ -283,26 +299,26 @@ class AddOtherAccountFragmentTest : BaseTest() { val someFailTextToChangeRightValue = "123" val fieldIdentifiersWithIncorrectData = intArrayOf( - R.id.editTextEmail, - R.id.editTextUserName, - R.id.editTextImapServer, - R.id.editTextImapPort, - R.id.editTextSmtpServer, - R.id.editTextSmtpPort, - R.id.editTextSmtpUsername, - R.id.editTextSmtpPassword + R.id.editTextEmail, + R.id.editTextUserName, + R.id.editTextImapServer, + R.id.editTextImapPort, + R.id.editTextSmtpServer, + R.id.editTextSmtpPort, + R.id.editTextSmtpUsername, + R.id.editTextSmtpPassword ) val correctData = arrayOf( - creds.email, - creds.username, - creds.password, - creds.imapServer, - creds.imapPort.toString(), - creds.smtpServer, - creds.smtpPort.toString(), - creds.smtpSigInUsername, - creds.smtpSignInPassword + creds.email, + creds.username, + creds.password, + creds.imapServer, + creds.imapPort.toString(), + creds.smtpServer, + creds.smtpPort.toString(), + creds.smtpSigInUsername, + creds.smtpSignInPassword ) val numberOfChecks = if (creds.hasCustomSignInForSmtp) { @@ -313,25 +329,36 @@ class AddOtherAccountFragmentTest : BaseTest() { for (i in 0 until numberOfChecks) { onView(withId(fieldIdentifiersWithIncorrectData[i])) - .perform(scrollTo(), typeText(someFailTextToChangeRightValue), closeSoftKeyboard()) + .perform(scrollTo(), typeText(someFailTextToChangeRightValue), closeSoftKeyboard()) onView(withId(R.id.buttonTryToConnect)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) - onView(anyOf(withText(startsWith(TestConstants.IMAP)), withText(startsWith(TestConstants.SMTP)))) - .check(matches(isDisplayed())) + onView( + anyOf( + withText(startsWith(TestConstants.IMAP)), + withText(startsWith(TestConstants.SMTP)) + ) + ) + .check(matches(isDisplayed())) - if (i in intArrayOf(R.id.editTextImapServer, R.id.editTextImapPort, R.id.editTextSmtpServer, R.id.editTextSmtpPort)) { + if (i in intArrayOf( + R.id.editTextImapServer, + R.id.editTextImapPort, + R.id.editTextSmtpServer, + R.id.editTextSmtpPort + ) + ) { onView(withText(getResString(R.string.network_error))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } onView(withText(getResString(R.string.cancel))) - .inRoot(isDialog()) - .check(matches(isDisplayed())) - .perform(click()) + .inRoot(isDialog()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(fieldIdentifiersWithIncorrectData[i])) - .perform(scrollTo(), clearText(), typeText(correctData[i]), closeSoftKeyboard()) + .perform(scrollTo(), clearText(), typeText(correctData[i]), closeSoftKeyboard()) } } @@ -352,9 +379,9 @@ class AddOtherAccountFragmentTest : BaseTest() { onView(withId(R.id.editTextEmail)) .perform(clearText(), typeText(creds.email), closeSoftKeyboard()) onView(withId(R.id.editTextPassword)) - .perform(clearText(), typeText(creds.password), closeSoftKeyboard()) + .perform(clearText(), typeText(creds.password), closeSoftKeyboard()) onView(withId(R.id.buttonTryToConnect)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) intended(hasComponent(EmailManagerActivity::class.java.name)) } @@ -365,10 +392,10 @@ class AddOtherAccountFragmentTest : BaseTest() { val user = AccountDaoManager.getUserWithMoreThan21Letters() FlowCryptRoomDatabase.getDatabase(getTargetContext()).accountDao().addAccount(user) PrivateKeysManager.saveKeyFromAssetsToDatabase( - accountEntity = user, - keyPath = "pgp/key_testing@flowcrypt.test_keyB_default.asc", - passphrase = TestConstants.DEFAULT_PASSWORD, - sourceType = KeyImportDetails.SourceType.EMAIL + accountEntity = user, + keyPath = "pgp/key_testing@flowcrypt.test_keyB_default.asc", + passphrase = TestConstants.DEFAULT_PASSWORD, + sourceType = KeyImportDetails.SourceType.EMAIL ) testWhenNoAccountsAndHasBackup() @@ -379,133 +406,155 @@ class AddOtherAccountFragmentTest : BaseTest() { val existedUser = AccountDaoManager.getDefaultAccountDao() FlowCryptRoomDatabase.getDatabase(getTargetContext()).accountDao().addAccount(existedUser) PrivateKeysManager.saveKeyFromAssetsToDatabase( - accountEntity = existedUser, - keyPath = "pgp/default@flowcrypt.test_fisrtKey_prv_default.asc", - passphrase = TestConstants.DEFAULT_PASSWORD, - sourceType = KeyImportDetails.SourceType.EMAIL + accountEntity = existedUser, + keyPath = "pgp/default@flowcrypt.test_fisrtKey_prv_default.asc", + passphrase = TestConstants.DEFAULT_PASSWORD, + sourceType = KeyImportDetails.SourceType.EMAIL ) onView(withId(R.id.editTextEmail)) - .perform(clearText(), typeText(existedUser.email), closeSoftKeyboard()) + .perform(clearText(), typeText(existedUser.email), closeSoftKeyboard()) onView(withId(R.id.editTextPassword)) - .perform(clearText(), typeText(existedUser.password), closeSoftKeyboard()) + .perform(clearText(), typeText(existedUser.password), closeSoftKeyboard()) onView(withId(R.id.buttonTryToConnect)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) checkIsSnackBarDisplayed(getResString(R.string.template_email_already_added, existedUser.email)) } - private fun checkSecurityTypeOpt(portViewId: Int, spinnerViewId: Int, option: SecurityType.Option, - portValue: String) { + private fun checkSecurityTypeOpt( + portViewId: Int, spinnerViewId: Int, option: SecurityType.Option, + portValue: String + ) { val someValue = "111" onView(withId(portViewId)) - .perform(scrollTo(), clearText(), typeText(someValue), closeSoftKeyboard()) + .perform(scrollTo(), clearText(), typeText(someValue), closeSoftKeyboard()) onView(withId(spinnerViewId)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) onData(allOf(`is`(instanceOf(SecurityType::class.java)), withSecurityTypeOption(option))) - .perform(click()) + .perform(click()) onView(withId(portViewId)) - .check(matches(withText(portValue))) + .check(matches(withText(portValue))) } private fun checkIsFieldEmptyWork(viewId: Int, stringIdForError: Int) { onView(withId(R.id.editTextEmail)) - .perform(scrollTo(), clearText(), typeText(authCreds.email), closeSoftKeyboard()) + .perform(scrollTo(), clearText(), typeText(authCreds.email), closeSoftKeyboard()) onView(withId(R.id.editTextPassword)) - .perform(clearText(), typeText(authCreds.password), closeSoftKeyboard()) + .perform(clearText(), typeText(authCreds.password), closeSoftKeyboard()) onView(withId(viewId)) - .perform(scrollTo(), clearText()) + .perform(scrollTo(), clearText()) onView(withId(R.id.buttonTryToConnect)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) val text = getResString(R.string.text_must_not_be_empty, getResString(stringIdForError)) onView(withText(text)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(com.google.android.material.R.id.snackbar_action)) - .check(matches(isDisplayed())).perform(click()) + .check(matches(isDisplayed())).perform(click()) } private fun fillAllFields(authCreds: AuthCredentials) { onView(withId(R.id.editTextEmail)) - .perform(clearText(), typeText(authCreds.email), closeSoftKeyboard()) + .perform(clearText(), typeText(authCreds.email), closeSoftKeyboard()) onView(withId(R.id.editTextUserName)) - .perform(clearText(), typeText(authCreds.username), closeSoftKeyboard()) + .perform(clearText(), typeText(authCreds.username), closeSoftKeyboard()) onView(withId(R.id.editTextPassword)) - .perform(clearText(), typeText(authCreds.password), closeSoftKeyboard()) + .perform(clearText(), typeText(authCreds.password), closeSoftKeyboard()) onView(withId(R.id.editTextImapServer)) - .perform(clearText(), typeText(authCreds.imapServer), closeSoftKeyboard()) + .perform(clearText(), typeText(authCreds.imapServer), closeSoftKeyboard()) onView(withId(R.id.spinnerImapSecurityType)) - .perform(scrollTo(), click()) - onData(allOf(`is`(instanceOf(SecurityType::class.java)), withSecurityTypeOption(authCreds.imapOpt))) - .perform(click()) + .perform(scrollTo(), click()) + onData( + allOf( + `is`(instanceOf(SecurityType::class.java)), + withSecurityTypeOption(authCreds.imapOpt) + ) + ) + .perform(click()) onView(withId(R.id.editTextImapPort)) - .perform(clearText(), typeText(authCreds.imapPort.toString()), closeSoftKeyboard()) + .perform(clearText(), typeText(authCreds.imapPort.toString()), closeSoftKeyboard()) onView(withId(R.id.editTextSmtpServer)) - .perform(clearText(), typeText(authCreds.smtpServer), closeSoftKeyboard()) + .perform(clearText(), typeText(authCreds.smtpServer), closeSoftKeyboard()) onView(withId(R.id.spinnerSmtpSecyrityType)) - .perform(scrollTo(), click()) - onData(allOf(`is`(instanceOf(SecurityType::class.java)), withSecurityTypeOption(authCreds.smtpOpt))) - .perform(click()) + .perform(scrollTo(), click()) + onData( + allOf( + `is`(instanceOf(SecurityType::class.java)), + withSecurityTypeOption(authCreds.smtpOpt) + ) + ) + .perform(click()) onView(withId(R.id.editTextSmtpPort)) - .perform(clearText(), typeText(authCreds.smtpPort.toString()), closeSoftKeyboard()) + .perform(clearText(), typeText(authCreds.smtpPort.toString()), closeSoftKeyboard()) if (authCreds.hasCustomSignInForSmtp) { onView(withId(R.id.checkBoxRequireSignInForSmtp)) - .perform(click()) + .perform(click()) onView(withId(R.id.editTextSmtpUsername)) - .perform(clearText(), typeText(authCreds.smtpSigInUsername), closeSoftKeyboard()) + .perform(clearText(), typeText(authCreds.smtpSigInUsername), closeSoftKeyboard()) onView(withId(R.id.editTextSmtpPassword)) - .perform(clearText(), typeText(authCreds.smtpSignInPassword), closeSoftKeyboard()) + .perform(clearText(), typeText(authCreds.smtpSignInPassword), closeSoftKeyboard()) } } private fun clearAllFields() { onView(withId(R.id.editTextEmail)) - .perform(scrollTo(), clearText(), closeSoftKeyboard()) + .perform(scrollTo(), clearText(), closeSoftKeyboard()) onView(withId(R.id.editTextUserName)) - .perform(scrollTo(), clearText(), closeSoftKeyboard()) + .perform(scrollTo(), clearText(), closeSoftKeyboard()) onView(withId(R.id.editTextPassword)) - .perform(scrollTo(), clearText(), closeSoftKeyboard()) + .perform(scrollTo(), clearText(), closeSoftKeyboard()) onView(withId(R.id.editTextImapServer)) - .perform(scrollTo(), clearText(), closeSoftKeyboard()) + .perform(scrollTo(), clearText(), closeSoftKeyboard()) onView(withId(R.id.spinnerImapSecurityType)) - .perform(scrollTo(), click()) - onData(allOf(`is`(instanceOf(SecurityType::class.java)), withSecurityTypeOption(SecurityType.Option.NONE))) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) + onData( + allOf( + `is`(instanceOf(SecurityType::class.java)), + withSecurityTypeOption(SecurityType.Option.NONE) + ) + ) + .perform(scrollTo(), click()) onView(withId(R.id.editTextImapPort)) - .perform(scrollTo(), clearText(), closeSoftKeyboard()) + .perform(scrollTo(), clearText(), closeSoftKeyboard()) onView(withId(R.id.editTextSmtpServer)) - .perform(scrollTo(), clearText(), closeSoftKeyboard()) + .perform(scrollTo(), clearText(), closeSoftKeyboard()) onView(withId(R.id.spinnerSmtpSecyrityType)) - .perform(scrollTo(), click()) - onData(allOf(`is`(instanceOf(SecurityType::class.java)), withSecurityTypeOption(SecurityType.Option.NONE))) - .perform(click()) + .perform(scrollTo(), click()) + onData( + allOf( + `is`(instanceOf(SecurityType::class.java)), + withSecurityTypeOption(SecurityType.Option.NONE) + ) + ) + .perform(click()) onView(withId(R.id.editTextSmtpPort)) - .perform(clearText(), closeSoftKeyboard()) + .perform(clearText(), closeSoftKeyboard()) onView(withId(R.id.checkBoxRequireSignInForSmtp)) - .check(matches(isNotChecked())) - .perform(scrollTo(), click()) + .check(matches(isNotChecked())) + .perform(scrollTo(), click()) onView(withId(R.id.editTextSmtpUsername)) - .perform(scrollTo(), clearText(), closeSoftKeyboard()) + .perform(scrollTo(), clearText(), closeSoftKeyboard()) onView(withId(R.id.editTextSmtpPassword)) - .perform(scrollTo(), clearText(), closeSoftKeyboard()) + .perform(scrollTo(), clearText(), closeSoftKeyboard()) } private fun enableAdvancedMode() { onView(withId(R.id.checkBoxAdvancedMode)) - .check(matches(isNotChecked())) - .perform(scrollTo(), click()) + .check(matches(isNotChecked())) + .perform(scrollTo(), click()) } companion object { private const val IMAP_SERVER_PREFIX = "imap." private const val SMTP_SERVER_PREFIX = "smtp." } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/AttesterSettingsActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/AttesterSettingsActivityTest.kt index 30718e655f..633909dc79 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/AttesterSettingsActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/AttesterSettingsActivityTest.kt @@ -50,35 +50,37 @@ class AttesterSettingsActivityTest : BaseTest() { @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(accountRule) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(accountRule) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test @NotReadyForCI fun testKeysExistOnAttester() { onView(withId(R.id.rVAttester)) - .check(matches(not(withEmptyRecyclerView()))).check(matches(isDisplayed())) + .check(matches(not(withEmptyRecyclerView()))).check(matches(isDisplayed())) onView(withId(R.id.empty)) - .check(matches(not(isDisplayed()))) + .check(matches(not(isDisplayed()))) } companion object { @get:ClassRule @JvmStatic - val mockWebServerRule = FlowCryptMockWebServerRule(TestConstants.MOCK_WEB_SERVER_PORT, object : Dispatcher() { - override fun dispatch(request: RecordedRequest): MockResponse { - if (request.path?.startsWith("/pub", ignoreCase = true) == true) { - val lastSegment = request.requestUrl?.pathSegments?.lastOrNull() - if (AccountDaoManager.getDefaultAccountDao().email.equals(lastSegment, true)) { - return MockResponse().setResponseCode(200).setBody(TestGeneralUtil.readResourcesAsString("1.txt")) + val mockWebServerRule = + FlowCryptMockWebServerRule(TestConstants.MOCK_WEB_SERVER_PORT, object : Dispatcher() { + override fun dispatch(request: RecordedRequest): MockResponse { + if (request.path?.startsWith("/pub", ignoreCase = true) == true) { + val lastSegment = request.requestUrl?.pathSegments?.lastOrNull() + if (AccountDaoManager.getDefaultAccountDao().email.equals(lastSegment, true)) { + return MockResponse().setResponseCode(200) + .setBody(TestGeneralUtil.readResourcesAsString("1.txt")) + } } - } - return MockResponse().setResponseCode(404) - } - }) + return MockResponse().setResponseCode(404) + } + }) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/BackupKeysActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/BackupKeysActivityTest.kt index 1b4b96b3cb..3e70d28c11 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/BackupKeysActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/BackupKeysActivityTest.kt @@ -65,52 +65,66 @@ class BackupKeysActivityTest : BaseTest() { @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(addAccountToDatabaseRule) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(addAccountToDatabaseRule) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test fun testEmailOptionHint() { onView(withId(R.id.radioButtonEmail)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(getResString(R.string.backup_as_email_hint))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test fun testDownloadOptionHint() { onView(withId(R.id.radioButtonDownload)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(getResString(R.string.backup_as_download_hint))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test fun testNoKeysEmailOption() { onView(withId(R.id.radioButtonEmail)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(R.id.buttonBackupAction)) - .check(matches(isDisplayed())) - .perform(click()) - onView(withText(getResString(R.string.there_are_no_private_keys, AccountDaoManager.getDefaultAccountDao().email))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) + .perform(click()) + onView( + withText( + getResString( + R.string.there_are_no_private_keys, + AccountDaoManager.getDefaultAccountDao().email + ) + ) + ) + .check(matches(isDisplayed())) } @Test fun testNoKeysDownloadOption() { onView(withId(R.id.radioButtonDownload)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(R.id.buttonBackupAction)) - .check(matches(isDisplayed())) - .perform(click()) - onView(withText(getResString(R.string.there_are_no_private_keys, AccountDaoManager.getDefaultAccountDao().email))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) + .perform(click()) + onView( + withText( + getResString( + R.string.there_are_no_private_keys, + AccountDaoManager.getDefaultAccountDao().email + ) + ) + ) + .check(matches(isDisplayed())) } @Test @@ -118,8 +132,8 @@ class BackupKeysActivityTest : BaseTest() { fun testSuccessEmailOption() { addFirstKeyWithStrongPassword() onView(withId(R.id.buttonBackupAction)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) assertTrue(activityScenarioRule.scenario.result.resultCode == Activity.RESULT_OK) } @@ -134,15 +148,15 @@ class BackupKeysActivityTest : BaseTest() { fun testSuccessDownloadOption() { addFirstKeyWithStrongPassword() onView(withId(R.id.radioButtonDownload)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) val file = TestGeneralUtil.createFileAndFillWithContent("key.asc", "") intendingFileChoose(file) onView(withId(R.id.buttonBackupAction)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) assertTrue(activityScenarioRule.scenario.result.resultCode == Activity.RESULT_OK) @@ -159,14 +173,14 @@ class BackupKeysActivityTest : BaseTest() { fun testShowWeakPasswordHintForDownloadOption() { addFirstKeyWithDefaultPassword() onView(withId(R.id.radioButtonDownload)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) intendingFileChoose(File("")) onView(withId(R.id.buttonBackupAction)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(getResString(R.string.pass_phrase_is_too_weak))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test @@ -174,24 +188,24 @@ class BackupKeysActivityTest : BaseTest() { fun testShowWeakPasswordHintForEmailOption() { addFirstKeyWithDefaultPassword() onView(withId(R.id.buttonBackupAction)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(getResString(R.string.pass_phrase_is_too_weak))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test fun testFixWeakPasswordForDownloadOption() { addFirstKeyWithDefaultPassword() onView(withId(R.id.radioButtonDownload)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) intendingFileChoose(File("")) onView(withId(R.id.buttonBackupAction)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) intending(hasComponent(ComponentName(getTargetContext(), ChangePassPhraseActivity::class.java))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) checkIsSnackbarDisplayedAndClick(getResString(R.string.pass_phrase_is_too_weak)) assertTrue(activityScenarioRule.scenario.state == Lifecycle.State.RESUMED) @@ -202,10 +216,10 @@ class BackupKeysActivityTest : BaseTest() { fun testFixWeakPasswordForEmailOption() { addFirstKeyWithDefaultPassword() onView(withId(R.id.buttonBackupAction)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) intending(hasComponent(ComponentName(getTargetContext(), ChangePassPhraseActivity::class.java))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) checkIsSnackbarDisplayedAndClick(getResString(R.string.pass_phrase_is_too_weak)) assertTrue(activityScenarioRule.scenario.state == Lifecycle.State.RESUMED) } @@ -216,10 +230,10 @@ class BackupKeysActivityTest : BaseTest() { addFirstKeyWithStrongPassword() addSecondKeyWithStrongSecondPassword() onView(withId(R.id.buttonBackupAction)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) intending(hasComponent(ComponentName(getTargetContext(), ChangePassPhraseActivity::class.java))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) checkIsSnackbarDisplayedAndClick(getResString(R.string.different_pass_phrases)) assertTrue(activityScenarioRule.scenario.state == Lifecycle.State.RESUMED) } @@ -229,14 +243,14 @@ class BackupKeysActivityTest : BaseTest() { addFirstKeyWithStrongPassword() addSecondKeyWithStrongSecondPassword() onView(withId(R.id.radioButtonDownload)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) intendingFileChoose(File("")) onView(withId(R.id.buttonBackupAction)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) intending(hasComponent(ComponentName(getTargetContext(), ChangePassPhraseActivity::class.java))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) checkIsSnackbarDisplayedAndClick(getResString(R.string.different_pass_phrases)) assertTrue(activityScenarioRule.scenario.state == Lifecycle.State.RESUMED) } @@ -244,45 +258,49 @@ class BackupKeysActivityTest : BaseTest() { private fun intendingFileChoose(file: File) { val resultData = Intent() resultData.data = Uri.fromFile(file) - intending(allOf(hasAction(Intent.ACTION_CREATE_DOCUMENT), + intending( + allOf( + hasAction(Intent.ACTION_CREATE_DOCUMENT), hasCategories(hasItem(equalTo(Intent.CATEGORY_OPENABLE))), - hasType(Constants.MIME_TYPE_PGP_KEY))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)) + hasType(Constants.MIME_TYPE_PGP_KEY) + ) + ) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)) } private fun addFirstKeyWithDefaultPassword() { PrivateKeysManager.saveKeyFromAssetsToDatabase( - accountEntity = addAccountToDatabaseRule.account, - keyPath = "pgp/default@flowcrypt.test_fisrtKey_prv_default.asc", - passphrase = TestConstants.DEFAULT_PASSWORD, - sourceType = KeyImportDetails.SourceType.EMAIL + accountEntity = addAccountToDatabaseRule.account, + keyPath = "pgp/default@flowcrypt.test_fisrtKey_prv_default.asc", + passphrase = TestConstants.DEFAULT_PASSWORD, + sourceType = KeyImportDetails.SourceType.EMAIL ) } private fun addFirstKeyWithStrongPassword() { PrivateKeysManager.saveKeyFromAssetsToDatabase( - accountEntity = addAccountToDatabaseRule.account, - keyPath = "pgp/default@flowcrypt.test_fisrtKey_prv_strong.asc", - passphrase = TestConstants.DEFAULT_STRONG_PASSWORD, - sourceType = KeyImportDetails.SourceType.EMAIL + accountEntity = addAccountToDatabaseRule.account, + keyPath = "pgp/default@flowcrypt.test_fisrtKey_prv_strong.asc", + passphrase = TestConstants.DEFAULT_STRONG_PASSWORD, + sourceType = KeyImportDetails.SourceType.EMAIL ) } private fun addSecondKeyWithStrongPassword() { PrivateKeysManager.saveKeyFromAssetsToDatabase( - accountEntity = addAccountToDatabaseRule.account, - keyPath = TestConstants.DEFAULT_SECOND_KEY_PRV_STRONG, - passphrase = TestConstants.DEFAULT_STRONG_PASSWORD, - sourceType = KeyImportDetails.SourceType.EMAIL + accountEntity = addAccountToDatabaseRule.account, + keyPath = TestConstants.DEFAULT_SECOND_KEY_PRV_STRONG, + passphrase = TestConstants.DEFAULT_STRONG_PASSWORD, + sourceType = KeyImportDetails.SourceType.EMAIL ) } private fun addSecondKeyWithStrongSecondPassword() { PrivateKeysManager.saveKeyFromAssetsToDatabase( - accountEntity = addAccountToDatabaseRule.account, - keyPath = "pgp/default@flowcrypt.test_secondKey_prv_strong_second.asc", - passphrase = TestConstants.DEFAULT_SECOND_STRONG_PASSWORD, - sourceType = KeyImportDetails.SourceType.EMAIL + accountEntity = addAccountToDatabaseRule.account, + keyPath = "pgp/default@flowcrypt.test_secondKey_prv_strong_second.asc", + passphrase = TestConstants.DEFAULT_SECOND_STRONG_PASSWORD, + sourceType = KeyImportDetails.SourceType.EMAIL ) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ChangePassPhraseActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ChangePassPhraseActivityTest.kt index 115bce9bf5..02ed4b6e20 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ChangePassPhraseActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ChangePassPhraseActivityTest.kt @@ -47,28 +47,28 @@ class ChangePassPhraseActivityTest : BasePassphraseActivityTest() { @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(addAccountToDatabaseRule) - .around(AddPrivateKeyToDatabaseRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(addAccountToDatabaseRule) + .around(AddPrivateKeyToDatabaseRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test @DependsOnMailServer fun testUseCorrectPassPhrase() { onView(withId(R.id.editTextKeyPassword)) - .check(matches(isDisplayed())) - .perform(replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) + .check(matches(isDisplayed())) + .perform(replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) onView(withId(R.id.buttonSetPassPhrase)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(R.id.editTextKeyPasswordSecond)) - .check(matches(isDisplayed())) - .perform(replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) + .check(matches(isDisplayed())) + .perform(replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) onView(withId(R.id.buttonConfirmPassPhrases)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) Assert.assertTrue(activityScenarioRule.scenario.result.resultCode == Activity.RESULT_OK) } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CheckKeysActivityTestMultiBackups.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CheckKeysActivityTestMultiBackups.kt index 6ba332e1f2..3bff37ca23 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CheckKeysActivityTestMultiBackups.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CheckKeysActivityTestMultiBackups.kt @@ -45,16 +45,17 @@ import org.junit.runner.RunWith @MediumTest @RunWith(AndroidJUnit4::class) class CheckKeysActivityTestMultiBackups : BaseTest() { - override val activeActivityRule = lazyActivityScenarioRule(launchActivity = false) + override val activeActivityRule = + lazyActivityScenarioRule(launchActivity = false) override val activityScenario: ActivityScenario<*>? get() = activeActivityRule.scenario @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(RetryRule.DEFAULT) - .around(activeActivityRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(RetryRule.DEFAULT) + .around(activeActivityRule) + .around(ScreenshotTestRule()) /** * There are two keys (all keys are different and have different pass phrases). Only one key from two keys is using. @@ -62,8 +63,9 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { @Test fun testUseTwoKeysFirstCombination() { val keysPaths = arrayOf( - "pgp/key_testing@flowcrypt.test_keyA_strong.asc", - "pgp/key_testing@flowcrypt.test_keyB_default.asc") + "pgp/key_testing@flowcrypt.test_keyA_strong.asc", + "pgp/key_testing@flowcrypt.test_keyB_default.asc" + ) launchActivity(keysPaths) checkKeysTitleAtStart(2) @@ -78,8 +80,9 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { @Test fun testUseTwoKeysSecondCombination() { val keysPaths = arrayOf( - "pgp/key_testing@flowcrypt.test_keyA_strong.asc", - "pgp/key_testing@flowcrypt.test_keyB_default.asc") + "pgp/key_testing@flowcrypt.test_keyA_strong.asc", + "pgp/key_testing@flowcrypt.test_keyB_default.asc" + ) launchActivity(keysPaths) checkKeysTitleAtStart(2) @@ -96,8 +99,9 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { @Test fun testUseTwoKeysWithSamePasswordThirdCombination() { val keysPaths = arrayOf( - "pgp/key_testing@flowcrypt.test_keyA_strong.asc", - "pgp/key_testing@flowcrypt.test_keyC_strong.asc") + "pgp/key_testing@flowcrypt.test_keyA_strong.asc", + "pgp/key_testing@flowcrypt.test_keyC_strong.asc" + ) launchActivity(keysPaths) checkKeysTitleAtStart(2) @@ -113,8 +117,9 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { @Test fun testUseTwoKeysFourthCombination() { val keysPaths = arrayOf( - "pgp/key_testing@flowcrypt.test_keyC_default.asc", - "pgp/key_testing@flowcrypt.test_keyC_strong.asc") + "pgp/key_testing@flowcrypt.test_keyC_default.asc", + "pgp/key_testing@flowcrypt.test_keyC_strong.asc" + ) launchActivity(keysPaths) checkKeysTitleAtStart(1) @@ -130,8 +135,9 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { @Test fun testUseTwoKeysFifthCombination() { val keysPaths = arrayOf( - "pgp/key_testing@flowcrypt.test_keyC_default.asc", - "pgp/key_testing@flowcrypt.test_keyC_strong.asc") + "pgp/key_testing@flowcrypt.test_keyC_default.asc", + "pgp/key_testing@flowcrypt.test_keyC_strong.asc" + ) launchActivity(keysPaths) checkKeysTitleAtStart(1) @@ -147,9 +153,10 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { @Test fun testUseThreeFirstCombination() { val keysPaths = arrayOf( - "pgp/key_testing@flowcrypt.test_keyA_strong.asc", - "pgp/key_testing@flowcrypt.test_keyB_default.asc", - "pgp/key_testing@flowcrypt.test_keyC_default.asc") + "pgp/key_testing@flowcrypt.test_keyA_strong.asc", + "pgp/key_testing@flowcrypt.test_keyB_default.asc", + "pgp/key_testing@flowcrypt.test_keyC_default.asc" + ) launchActivity(keysPaths) checkKeysTitleAtStart(3) @@ -165,9 +172,10 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { @Test fun testUseThreeKeysSecondCombination() { val keysPaths = arrayOf( - "pgp/key_testing@flowcrypt.test_keyA_strong.asc", - "pgp/key_testing@flowcrypt.test_keyB_default.asc", - "pgp/key_testing@flowcrypt.test_keyC_strong.asc") + "pgp/key_testing@flowcrypt.test_keyA_strong.asc", + "pgp/key_testing@flowcrypt.test_keyB_default.asc", + "pgp/key_testing@flowcrypt.test_keyC_strong.asc" + ) launchActivity(keysPaths) checkKeysTitleAtStart(3) @@ -183,9 +191,10 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { @Test fun testUseThreeKeysThirdCombination() { val keysPaths = arrayOf( - "pgp/key_testing@flowcrypt.test_keyA_strong.asc", - "pgp/key_testing@flowcrypt.test_keyB_default.asc", - "pgp/key_testing@flowcrypt.test_keyC_default.asc") + "pgp/key_testing@flowcrypt.test_keyA_strong.asc", + "pgp/key_testing@flowcrypt.test_keyB_default.asc", + "pgp/key_testing@flowcrypt.test_keyC_default.asc" + ) launchActivity(keysPaths) checkKeysTitleAtStart(3) @@ -203,9 +212,10 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { @Test fun testUseThreeKeysFourthCombination() { val keysPaths = arrayOf( - "pgp/key_testing@flowcrypt.test_keyA_strong.asc", - "pgp/key_testing@flowcrypt.test_keyB_default.asc", - "pgp/key_testing@flowcrypt.test_keyC_strong.asc") + "pgp/key_testing@flowcrypt.test_keyA_strong.asc", + "pgp/key_testing@flowcrypt.test_keyB_default.asc", + "pgp/key_testing@flowcrypt.test_keyC_strong.asc" + ) launchActivity(keysPaths) checkKeysTitleAtStart(3) @@ -223,9 +233,10 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { @Test fun testUseThreeKeysFifthCombination() { val keysPaths = arrayOf( - "pgp/key_testing@flowcrypt.test_keyB_default.asc", - "pgp/key_testing@flowcrypt.test_keyC_default.asc", - "pgp/key_testing@flowcrypt.test_keyC_strong.asc") + "pgp/key_testing@flowcrypt.test_keyB_default.asc", + "pgp/key_testing@flowcrypt.test_keyC_default.asc", + "pgp/key_testing@flowcrypt.test_keyC_strong.asc" + ) launchActivity(keysPaths) checkKeysTitleAtStart(2) @@ -241,9 +252,10 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { @Test fun testUseThreeKeysSixthCombination() { val keysPaths = arrayOf( - "pgp/key_testing@flowcrypt.test_keyA_strong.asc", - "pgp/key_testing@flowcrypt.test_keyC_default.asc", - "pgp/key_testing@flowcrypt.test_keyC_strong.asc") + "pgp/key_testing@flowcrypt.test_keyA_strong.asc", + "pgp/key_testing@flowcrypt.test_keyC_default.asc", + "pgp/key_testing@flowcrypt.test_keyC_strong.asc" + ) launchActivity(keysPaths) checkKeysTitleAtStart(2) @@ -259,9 +271,10 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { @Test fun testUseThreeKeysSeventhCombination() { val keysPaths = arrayOf( - "pgp/key_testing@flowcrypt.test_keyB_default.asc", - "pgp/key_testing@flowcrypt.test_keyC_default.asc", - "pgp/key_testing@flowcrypt.test_keyC_strong.asc") + "pgp/key_testing@flowcrypt.test_keyB_default.asc", + "pgp/key_testing@flowcrypt.test_keyC_default.asc", + "pgp/key_testing@flowcrypt.test_keyC_strong.asc" + ) launchActivity(keysPaths) checkKeysTitleAtStart(2) @@ -280,10 +293,11 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { @Test fun testUseFourKeysFirstCombination() { val keysPaths = arrayOf( - "pgp/key_testing@flowcrypt.test_keyA_strong.asc", - "pgp/key_testing@flowcrypt.test_keyB_default.asc", - "pgp/key_testing@flowcrypt.test_keyC_default.asc", - "pgp/key_testing@flowcrypt.test_keyC_strong.asc") + "pgp/key_testing@flowcrypt.test_keyA_strong.asc", + "pgp/key_testing@flowcrypt.test_keyB_default.asc", + "pgp/key_testing@flowcrypt.test_keyC_default.asc", + "pgp/key_testing@flowcrypt.test_keyC_strong.asc" + ) launchActivity(keysPaths) checkKeysTitleAtStart(3) @@ -300,10 +314,11 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { @Test fun testUseFourKeysSecondCombination() { val keysPaths = arrayOf( - "pgp/key_testing@flowcrypt.test_keyA_strong.asc", - "pgp/key_testing@flowcrypt.test_keyB_default.asc", - "pgp/key_testing@flowcrypt.test_keyC_default.asc", - "pgp/key_testing@flowcrypt.test_keyC_strong.asc") + "pgp/key_testing@flowcrypt.test_keyA_strong.asc", + "pgp/key_testing@flowcrypt.test_keyB_default.asc", + "pgp/key_testing@flowcrypt.test_keyC_default.asc", + "pgp/key_testing@flowcrypt.test_keyC_strong.asc" + ) launchActivity(keysPaths) checkKeysTitleAtStart(3) @@ -420,14 +435,17 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { checkKeysTitleAtStart(4, keysPaths, KeyImportDetails.SourceType.FILE) } - private fun launchActivity(keysPaths: Array, sourceType: KeyImportDetails.SourceType = KeyImportDetails.SourceType.EMAIL) { + private fun launchActivity( + keysPaths: Array, + sourceType: KeyImportDetails.SourceType = KeyImportDetails.SourceType.EMAIL + ) { activeActivityRule.launch(getStartCheckKeysActivityIntent(keysPaths, sourceType)) registerAllIdlingResources() } private fun checkSkipRemainingBackupsButton() { onView(withId(R.id.buttonSkipRemainingBackups)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) Assert.assertTrue(activeActivityRule.getNonNullScenario().result.resultCode == CheckKeysActivity.RESULT_SKIP_REMAINING_KEYS) } @@ -439,40 +457,64 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { */ private fun typePassword(password: String) { onView(withId(R.id.editTextKeyPassword)) - .perform(scrollTo(), typeText(password), closeSoftKeyboard()) + .perform(scrollTo(), typeText(password), closeSoftKeyboard()) onView(withId(R.id.buttonPositiveAction)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) } - private fun checkKeysTitle(quantityOfKeysUsed: Int, totalQuantityOfKeys: Int, quantityOfRemainingKeys: Int) { + private fun checkKeysTitle( + quantityOfKeysUsed: Int, + totalQuantityOfKeys: Int, + quantityOfRemainingKeys: Int + ) { onView(withId(R.id.textViewSubTitle)) - .check(matches(isDisplayed())) - .check(matches(withText(getQuantityString(R.plurals.not_recovered_all_keys, - quantityOfRemainingKeys, quantityOfKeysUsed, totalQuantityOfKeys, quantityOfRemainingKeys)))) + .check(matches(isDisplayed())) + .check( + matches( + withText( + getQuantityString( + R.plurals.not_recovered_all_keys, + quantityOfRemainingKeys, + quantityOfKeysUsed, + totalQuantityOfKeys, + quantityOfRemainingKeys + ) + ) + ) + ) } - private fun checkKeysTitleAtStart(expectedKeyCount: Int, keysPaths: Array? = null, - sourceType: KeyImportDetails.SourceType = KeyImportDetails.SourceType.EMAIL) { + private fun checkKeysTitleAtStart( + expectedKeyCount: Int, keysPaths: Array? = null, + sourceType: KeyImportDetails.SourceType = KeyImportDetails.SourceType.EMAIL + ) { val text: String when (sourceType) { KeyImportDetails.SourceType.FILE -> { assert(keysPaths?.size == 1) val fileName = FilenameUtils.getName(keysPaths?.first()) - text = getQuantityString(R.plurals.file_contains_some_amount_of_keys, - expectedKeyCount, fileName, expectedKeyCount) + text = getQuantityString( + R.plurals.file_contains_some_amount_of_keys, + expectedKeyCount, fileName, expectedKeyCount + ) } else -> { - text = getQuantityString(R.plurals.found_backup_of_your_account_key, - expectedKeyCount, expectedKeyCount) + text = getQuantityString( + R.plurals.found_backup_of_your_account_key, + expectedKeyCount, expectedKeyCount + ) } } onView(withId(R.id.textViewSubTitle)) - .check(matches(isDisplayed())) - .check(matches(withText(text))) + .check(matches(isDisplayed())) + .check(matches(withText(text))) } - private fun getStartCheckKeysActivityIntent(keysPaths: Array, sourceType: KeyImportDetails.SourceType = KeyImportDetails.SourceType.EMAIL): Intent { + private fun getStartCheckKeysActivityIntent( + keysPaths: Array, + sourceType: KeyImportDetails.SourceType = KeyImportDetails.SourceType.EMAIL + ): Intent { val keyDetailsList = PrivateKeysManager.getKeysFromAssets(keysPaths, true) val bottomTitle: String @@ -480,23 +522,27 @@ class CheckKeysActivityTestMultiBackups : BaseTest() { KeyImportDetails.SourceType.FILE -> { assert(keysPaths.size == 1) val fileName = FilenameUtils.getName(keysPaths.first()) - bottomTitle = getQuantityString(R.plurals.file_contains_some_amount_of_keys, - keyDetailsList.size, fileName, keyDetailsList.size) + bottomTitle = getQuantityString( + R.plurals.file_contains_some_amount_of_keys, + keyDetailsList.size, fileName, keyDetailsList.size + ) } else -> { - bottomTitle = getQuantityString(R.plurals.found_backup_of_your_account_key, - keyDetailsList.size, keyDetailsList.size) + bottomTitle = getQuantityString( + R.plurals.found_backup_of_your_account_key, + keyDetailsList.size, keyDetailsList.size + ) } } return CheckKeysActivity.newIntent( - context = getTargetContext(), - privateKeys = keyDetailsList, - sourceType = sourceType, - subTitle = bottomTitle, - positiveBtnTitle = getTargetContext().getString(R.string.continue_), - negativeBtnTitle = getTargetContext().getString(R.string.choose_another_key), - isExtraImportOpt = sourceType != KeyImportDetails.SourceType.EMAIL + context = getTargetContext(), + privateKeys = keyDetailsList, + sourceType = sourceType, + subTitle = bottomTitle, + positiveBtnTitle = getTargetContext().getString(R.string.continue_), + negativeBtnTitle = getTargetContext().getString(R.string.choose_another_key), + isExtraImportOpt = sourceType != KeyImportDetails.SourceType.EMAIL ) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CheckKeysActivityWithExistingKeysTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CheckKeysActivityWithExistingKeysTest.kt index c33f584abb..a4a2ae21e1 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CheckKeysActivityWithExistingKeysTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CheckKeysActivityWithExistingKeysTest.kt @@ -42,57 +42,66 @@ import org.junit.runner.RunWith @MediumTest @RunWith(AndroidJUnit4::class) class CheckKeysActivityWithExistingKeysTest : BaseTest() { - private val privateKeys = PrivateKeysManager.getKeysFromAssets(arrayOf("pgp/default@flowcrypt.test_fisrtKey_prv_default.asc"), true) + private val privateKeys = PrivateKeysManager.getKeysFromAssets( + arrayOf("pgp/default@flowcrypt.test_fisrtKey_prv_default.asc"), + true + ) override val activityScenarioRule = activityScenarioRule( - CheckKeysActivity.newIntent(getTargetContext(), - privateKeys = privateKeys, - sourceType = KeyImportDetails.SourceType.EMAIL, - subTitle = getQuantityString(R.plurals.found_backup_of_your_account_key, - privateKeys.size, privateKeys.size), - positiveBtnTitle = getTargetContext().getString(R.string.continue_), - negativeBtnTitle = getTargetContext().getString(R.string.use_another_account)) + CheckKeysActivity.newIntent( + getTargetContext(), + privateKeys = privateKeys, + sourceType = KeyImportDetails.SourceType.EMAIL, + subTitle = getQuantityString( + R.plurals.found_backup_of_your_account_key, + privateKeys.size, privateKeys.size + ), + positiveBtnTitle = getTargetContext().getString(R.string.continue_), + negativeBtnTitle = getTargetContext().getString(R.string.use_another_account) + ) ) private val addAccountToDatabaseRule = AddAccountToDatabaseRule() @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(addAccountToDatabaseRule) - .around(AddPrivateKeyToDatabaseRule( - accountEntity = addAccountToDatabaseRule.account, - keyPath = "pgp/not_attester_user@flowcrypt.test_prv_default.asc", - passphrase = TestConstants.DEFAULT_PASSWORD, - sourceType = KeyImportDetails.SourceType.EMAIL - )) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(addAccountToDatabaseRule) + .around( + AddPrivateKeyToDatabaseRule( + accountEntity = addAccountToDatabaseRule.account, + keyPath = "pgp/not_attester_user@flowcrypt.test_prv_default.asc", + passphrase = TestConstants.DEFAULT_PASSWORD, + sourceType = KeyImportDetails.SourceType.EMAIL + ) + ) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test fun testShowMsgEmptyPassPhrase() { Espresso.closeSoftKeyboard() onView(withId(R.id.buttonPositiveAction)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) checkIsSnackbarDisplayedAndClick(getResString(R.string.passphrase_must_be_non_empty)) } @Test fun testUseIncorrectPassPhrase() { onView(withId(R.id.editTextKeyPassword)) - .perform(scrollTo(), typeText("some pass phrase"), closeSoftKeyboard()) + .perform(scrollTo(), typeText("some pass phrase"), closeSoftKeyboard()) onView(withId(R.id.buttonPositiveAction)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) checkIsSnackbarDisplayedAndClick(getResString(R.string.password_is_incorrect)) } @Test fun testUseCorrectPassPhrase() { onView(withId(R.id.editTextKeyPassword)) - .perform(scrollTo(), typeText(TestConstants.DEFAULT_PASSWORD), closeSoftKeyboard()) + .perform(scrollTo(), typeText(TestConstants.DEFAULT_PASSWORD), closeSoftKeyboard()) onView(withId(R.id.buttonPositiveAction)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) Assert.assertTrue(activityScenarioRule.scenario.result.resultCode == Activity.RESULT_OK) } @@ -101,7 +110,7 @@ class CheckKeysActivityWithExistingKeysTest : BaseTest() { fun testCheckClickButtonNegative() { Espresso.closeSoftKeyboard() onView(withId(R.id.buttonNegativeAction)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) Assert.assertTrue(activityScenarioRule.scenario.result.resultCode == CheckKeysActivity.RESULT_NEGATIVE) } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CheckKeysActivityWithoutExistingKeysTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CheckKeysActivityWithoutExistingKeysTest.kt index a4c3022c85..31903390d6 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CheckKeysActivityWithoutExistingKeysTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CheckKeysActivityWithoutExistingKeysTest.kt @@ -40,48 +40,55 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class CheckKeysActivityWithoutExistingKeysTest : BaseTest() { - private val privateKeys = PrivateKeysManager.getKeysFromAssets(arrayOf("pgp/default@flowcrypt.test_fisrtKey_prv_default.asc"), true) + private val privateKeys = PrivateKeysManager.getKeysFromAssets( + arrayOf("pgp/default@flowcrypt.test_fisrtKey_prv_default.asc"), + true + ) override val activityScenarioRule = activityScenarioRule( - CheckKeysActivity.newIntent(getTargetContext(), - privateKeys, - KeyImportDetails.SourceType.EMAIL, - getQuantityString(R.plurals.found_backup_of_your_account_key, - privateKeys.size, privateKeys.size), - getTargetContext().getString(R.string.continue_), - getTargetContext().getString(R.string.use_another_account)) + CheckKeysActivity.newIntent( + getTargetContext(), + privateKeys, + KeyImportDetails.SourceType.EMAIL, + getQuantityString( + R.plurals.found_backup_of_your_account_key, + privateKeys.size, privateKeys.size + ), + getTargetContext().getString(R.string.continue_), + getTargetContext().getString(R.string.use_another_account) + ) ) @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test fun testShowMsgEmptyWarning() { Espresso.closeSoftKeyboard() onView(withId(R.id.buttonPositiveAction)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) checkIsSnackbarDisplayedAndClick(getResString(R.string.passphrase_must_be_non_empty)) } @Test fun testUseIncorrectPassPhrase() { onView(withId(R.id.editTextKeyPassword)) - .perform(scrollTo(), typeText("some pass phrase"), closeSoftKeyboard()) + .perform(scrollTo(), typeText("some pass phrase"), closeSoftKeyboard()) onView(withId(R.id.buttonPositiveAction)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) checkIsSnackbarDisplayedAndClick(getResString(R.string.password_is_incorrect)) } @Test fun testUseCorrectPassPhrase() { onView(withId(R.id.editTextKeyPassword)) - .perform(scrollTo(), typeText("android"), closeSoftKeyboard()) + .perform(scrollTo(), typeText("android"), closeSoftKeyboard()) onView(withId(R.id.buttonPositiveAction)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) Assert.assertTrue(activityScenarioRule.scenario.result.resultCode == Activity.RESULT_OK) } @@ -90,7 +97,7 @@ class CheckKeysActivityWithoutExistingKeysTest : BaseTest() { fun testCheckClickButtonNegative() { Espresso.closeSoftKeyboard() onView(withId(R.id.buttonNegativeAction)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) Assert.assertTrue(activityScenarioRule.scenario.result.resultCode == CheckKeysActivity.RESULT_NEGATIVE) } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ContactsSettingsActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ContactsSettingsActivityTest.kt index 44485395bc..b649e9c8b9 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ContactsSettingsActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ContactsSettingsActivityTest.kt @@ -50,11 +50,11 @@ class ContactsSettingsActivityTest : BaseTest() { @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(AddAccountToDatabaseRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(AddAccountToDatabaseRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test fun testShowHelpScreen() { @@ -64,9 +64,9 @@ class ContactsSettingsActivityTest : BaseTest() { @Test fun testEmptyList() { onView(withId(R.id.recyclerViewContacts)) - .check(matches(withEmptyRecyclerView())).check(matches(not(isDisplayed()))) + .check(matches(withEmptyRecyclerView())).check(matches(not(isDisplayed()))) onView(withId(R.id.emptyView)) - .check(matches(isDisplayed())).check(matches(withText(R.string.no_results))) + .check(matches(isDisplayed())).check(matches(withText(R.string.no_results))) } @Test @@ -77,32 +77,40 @@ class ContactsSettingsActivityTest : BaseTest() { Thread.sleep(2000) for (ignored in EMAILS) { onView(withId(R.id.recyclerViewContacts)) - .perform(actionOnItemAtPosition(0, ClickOnViewInRecyclerViewItem(R.id.imageButtonDeleteContact))) + .perform( + actionOnItemAtPosition( + 0, + ClickOnViewInRecyclerViewItem(R.id.imageButtonDeleteContact) + ) + ) } Thread.sleep(2000) onView(withId(R.id.emptyView)) - .check(matches(isDisplayed())).check(matches(withText(R.string.no_results))) + .check(matches(isDisplayed())).check(matches(withText(R.string.no_results))) clearContactsFromDatabase() } private fun addContactsToDatabase() { for (email in EMAILS) { val pgpContact = PgpContact(email, null, "", true, null, null, 0) - FlowCryptRoomDatabase.getDatabase(getTargetContext()).contactsDao().insert(pgpContact.toContactEntity()) + FlowCryptRoomDatabase.getDatabase(getTargetContext()).contactsDao() + .insert(pgpContact.toContactEntity()) } } companion object { private val EMAILS = arrayOf( - "contact_0@flowcrypt.test", - "contact_1@flowcrypt.test", - "contact_2@flowcrypt.test", - "contact_3@flowcrypt.test") + "contact_0@flowcrypt.test", + "contact_1@flowcrypt.test", + "contact_2@flowcrypt.test", + "contact_3@flowcrypt.test" + ) @AfterClass fun clearContactsFromDatabase() { for (email in EMAILS) { - val dao = FlowCryptRoomDatabase.getDatabase(ApplicationProvider.getApplicationContext()).contactsDao() + val dao = FlowCryptRoomDatabase.getDatabase(ApplicationProvider.getApplicationContext()) + .contactsDao() val contact = dao.getContactByEmail(email) ?: continue dao.delete(contact) diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityReplyAllTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityReplyAllTest.kt index 676d92ce35..0c8149a8b0 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityReplyAllTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityReplyAllTest.kt @@ -39,44 +39,51 @@ import org.junit.runner.RunWith @MediumTest @RunWith(AndroidJUnit4::class) class CreateMessageActivityReplyAllTest : BaseTest() { - override val activeActivityRule = lazyActivityScenarioRule(launchActivity = false) + override val activeActivityRule = + lazyActivityScenarioRule(launchActivity = false) override val activityScenario: ActivityScenario<*>? get() = activeActivityRule.scenario private val account = AccountDaoManager.getDefaultAccountDao() private val accountAliasesEntity = AccountAliasesEntity( - email = account.email, - accountType = account.accountType ?: "", - sendAsEmail = "alias@flowcrypt.test", - displayName = "Alias", - isDefault = true, - verificationStatus = "accepted") + email = account.email, + accountType = account.accountType ?: "", + sendAsEmail = "alias@flowcrypt.test", + displayName = "Alias", + isDefault = true, + verificationStatus = "accepted" + ) @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(AddAccountToDatabaseRule(account)) - .around(AddPrivateKeyToDatabaseRule()) - .around(RetryRule.DEFAULT) - .around(activeActivityRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(AddAccountToDatabaseRule(account)) + .around(AddPrivateKeyToDatabaseRule()) + .around(RetryRule.DEFAULT) + .around(activeActivityRule) + .around(ScreenshotTestRule()) @Test fun testReplyAllUsingGmailAlias() { - val msgInfo = getMsgInfo("messages/info/standard_msg_reply_all_via_gmail_alias.json", - "messages/mime/standard_msg_reply_to_header.txt") + val msgInfo = getMsgInfo( + "messages/info/standard_msg_reply_all_via_gmail_alias.json", + "messages/mime/standard_msg_reply_to_header.txt" + ) roomDatabase.accountAliasesDao().insert(accountAliasesEntity) - activeActivityRule.launch(CreateMessageActivity.generateIntent( + activeActivityRule.launch( + CreateMessageActivity.generateIntent( getTargetContext(), msgInfo, MessageType.REPLY_ALL, - MessageEncryptionType.STANDARD)) + MessageEncryptionType.STANDARD + ) + ) registerAllIdlingResources() Espresso.onView(ViewMatchers.withId(R.id.editTextRecipientCc)) - .check(ViewAssertions.matches(Matchers.not(ViewMatchers.isDisplayed()))) + .check(ViewAssertions.matches(Matchers.not(ViewMatchers.isDisplayed()))) } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityReplyTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityReplyTest.kt index 1c24987015..3e2fd46faf 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityReplyTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityReplyTest.kt @@ -39,34 +39,40 @@ import org.junit.runner.RunWith @MediumTest @RunWith(AndroidJUnit4::class) class CreateMessageActivityReplyTest : BaseTest() { - override val activeActivityRule = lazyActivityScenarioRule(launchActivity = false) + override val activeActivityRule = + lazyActivityScenarioRule(launchActivity = false) override val activityScenario: ActivityScenario<*>? get() = activeActivityRule.scenario @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(AddAccountToDatabaseRule()) - .around(AddPrivateKeyToDatabaseRule()) - .around(RetryRule.DEFAULT) - .around(activeActivityRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(AddAccountToDatabaseRule()) + .around(AddPrivateKeyToDatabaseRule()) + .around(RetryRule.DEFAULT) + .around(activeActivityRule) + .around(ScreenshotTestRule()) @Test fun testReplyToHeader() { - val msgInfo = getMsgInfo("messages/info/standard_msg_reply_to_header.json", - "messages/mime/standard_msg_reply_to_header.txt") - activeActivityRule.launch(CreateMessageActivity.generateIntent( + val msgInfo = getMsgInfo( + "messages/info/standard_msg_reply_to_header.json", + "messages/mime/standard_msg_reply_to_header.txt" + ) + activeActivityRule.launch( + CreateMessageActivity.generateIntent( getTargetContext(), msgInfo, MessageType.REPLY, - MessageEncryptionType.STANDARD)) + MessageEncryptionType.STANDARD + ) + ) registerAllIdlingResources() onView(withId(R.id.editTextRecipientTo)) - .check(matches(isDisplayed())) - .check(matches(withText(prepareChipText(msgInfo?.getReplyTo()?.first()?.address)))) + .check(matches(isDisplayed())) + .check(matches(withText(prepareChipText(msgInfo?.getReplyTo()?.first()?.address)))) } private fun prepareChipText(text: String?): String { @@ -78,4 +84,4 @@ class CreateMessageActivityReplyTest : BaseTest() { + chipSeparator + autoCorrectSeparator) } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt index 257e86353a..6f5be87dfb 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt @@ -99,7 +99,7 @@ import java.time.Instant class CreateMessageActivityTest : BaseTest() { override val useIntents: Boolean = true override val activeActivityRule = - lazyActivityScenarioRule(launchActivity = false) + lazyActivityScenarioRule(launchActivity = false) override val activityScenario: ActivityScenario<*>? get() = activeActivityRule.scenario @@ -109,22 +109,25 @@ class CreateMessageActivityTest : BaseTest() { @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(addAccountToDatabaseRule) - .around(addPrivateKeyToDatabaseRule) - .around(temporaryFolderRule) - .around(RetryRule.DEFAULT) - .around(activeActivityRule) - .around(ScreenshotTestRule()) - - private val intent: Intent = CreateMessageActivity.generateIntent(getTargetContext(), null, - MessageEncryptionType.ENCRYPTED) + .outerRule(ClearAppSettingsRule()) + .around(addAccountToDatabaseRule) + .around(addPrivateKeyToDatabaseRule) + .around(temporaryFolderRule) + .around(RetryRule.DEFAULT) + .around(activeActivityRule) + .around(ScreenshotTestRule()) + + private val intent: Intent = CreateMessageActivity.generateIntent( + getTargetContext(), null, + MessageEncryptionType.ENCRYPTED + ) private val defaultMsgEncryptionType: MessageEncryptionType = MessageEncryptionType.ENCRYPTED private val pgpContact: PgpContact get() { val details = PrivateKeysManager.getNodeKeyDetailsFromAssets( - "pgp/not_attester_user@flowcrypt.test_prv_default.asc") + "pgp/not_attester_user@flowcrypt.test_prv_default.asc" + ) return details.primaryPgpContact } @@ -133,13 +136,16 @@ class CreateMessageActivityTest : BaseTest() { activeActivityRule.launch(intent) registerAllIdlingResources() onView(withId(R.id.editTextRecipientTo)) - .check(matches(withText(isEmptyString()))) + .check(matches(withText(isEmptyString()))) onView(withId(R.id.menuActionSend)) - .check(matches(isDisplayed())) - .perform(click()) - onView(withText( - getResString(R.string.text_must_not_be_empty, getResString(R.string.prompt_recipients_to)))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) + .perform(click()) + onView( + withText( + getResString(R.string.text_must_not_be_empty, getResString(R.string.prompt_recipients_to)) + ) + ) + .check(matches(isDisplayed())) } @Test @@ -148,17 +154,24 @@ class CreateMessageActivityTest : BaseTest() { registerAllIdlingResources() onView(withId(R.id.layoutTo)) - .perform(scrollTo()) + .perform(scrollTo()) onView(withId(R.id.editTextRecipientTo)) - .perform(typeText(TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER)) + .perform(typeText(TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER)) onView(withId(R.id.editTextEmailSubject)) - .perform(scrollTo(), click(), typeText("subject"), clearText()) - .check(matches(withText(isEmptyString()))) + .perform(scrollTo(), click(), typeText("subject"), clearText()) + .check(matches(withText(isEmptyString()))) onView(withId(R.id.menuActionSend)) - .check(matches(isDisplayed())) - .perform(click()) - onView(withText(getResString(R.string.text_must_not_be_empty, getResString(R.string.prompt_subject)))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) + .perform(click()) + onView( + withText( + getResString( + R.string.text_must_not_be_empty, + getResString(R.string.prompt_subject) + ) + ) + ) + .check(matches(isDisplayed())) } @Test @@ -167,20 +180,20 @@ class CreateMessageActivityTest : BaseTest() { registerAllIdlingResources() onView(withId(R.id.layoutTo)) - .perform(scrollTo()) + .perform(scrollTo()) onView(withId(R.id.editTextRecipientTo)) - .perform(typeText(TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER)) + .perform(typeText(TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER)) onView(withId(R.id.editTextEmailSubject)) - .check(matches(isDisplayed())) - .perform(scrollTo(), click(), typeText(EMAIL_SUBJECT)) + .check(matches(isDisplayed())) + .perform(scrollTo(), click(), typeText(EMAIL_SUBJECT)) onView(withId(R.id.editTextEmailMessage)) - .perform(scrollTo()) - .check(matches(withText(isEmptyString()))) + .perform(scrollTo()) + .check(matches(withText(isEmptyString()))) onView(withId(R.id.menuActionSend)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(getResString(R.string.your_message_must_be_non_empty))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test @@ -191,8 +204,8 @@ class CreateMessageActivityTest : BaseTest() { if (defaultMsgEncryptionType != MessageEncryptionType.STANDARD) { openActionBarOverflowOrOptionsMenu(getTargetContext()) onView(withText(R.string.switch_to_standard_email)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) } checkIsDisplayedStandardAttributes() @@ -206,8 +219,8 @@ class CreateMessageActivityTest : BaseTest() { if (defaultMsgEncryptionType != MessageEncryptionType.ENCRYPTED) { openActionBarOverflowOrOptionsMenu(getTargetContext()) onView(withText(R.string.switch_to_secure_email)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) } checkIsDisplayedEncryptedAttributes() } @@ -223,15 +236,15 @@ class CreateMessageActivityTest : BaseTest() { checkIsDisplayedEncryptedAttributes() openActionBarOverflowOrOptionsMenu(getTargetContext()) onView(withText(R.string.switch_to_standard_email)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) checkIsDisplayedStandardAttributes() } else { checkIsDisplayedStandardAttributes() openActionBarOverflowOrOptionsMenu(getTargetContext()) onView(withText(R.string.switch_to_secure_email)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) checkIsDisplayedEncryptedAttributes() } } @@ -247,17 +260,17 @@ class CreateMessageActivityTest : BaseTest() { registerAllIdlingResources() onView(withText(R.string.compose)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(R.id.editTextFrom)) - .perform(scrollTo()) - .check(matches(withText(not(isEmptyString())))) + .perform(scrollTo()) + .check(matches(withText(not(isEmptyString())))) onView(withId(R.id.layoutTo)) - .perform(scrollTo()) + .perform(scrollTo()) onView(withId(R.id.editTextRecipientTo)) - .check(matches(withText(isEmptyString()))) + .check(matches(withText(isEmptyString()))) onView(withId(R.id.editTextEmailSubject)) - .perform(scrollTo()) - .check(matches(withText(isEmptyString()))) + .perform(scrollTo()) + .check(matches(withText(isEmptyString()))) } @Test @@ -269,17 +282,17 @@ class CreateMessageActivityTest : BaseTest() { for (invalidEmailAddress in invalidEmailAddresses) { onView(withId(R.id.layoutTo)) - .perform(scrollTo()) + .perform(scrollTo()) onView(withId(R.id.editTextRecipientTo)) - .perform(clearText(), typeText(invalidEmailAddress), closeSoftKeyboard()) + .perform(clearText(), typeText(invalidEmailAddress), closeSoftKeyboard()) onView(withId(R.id.menuActionSend)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(getResString(R.string.error_some_email_is_not_valid, invalidEmailAddress))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(com.google.android.material.R.id.snackbar_action)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) } } @@ -289,9 +302,9 @@ class CreateMessageActivityTest : BaseTest() { registerAllIdlingResources() onView(withId(R.id.layoutTo)) - .perform(scrollTo()) + .perform(scrollTo()) onView(withId(R.id.editTextRecipientTo)) - .perform(closeSoftKeyboard()) + .perform(closeSoftKeyboard()) for (att in atts) { addAttAndCheck(att) @@ -304,22 +317,26 @@ class CreateMessageActivityTest : BaseTest() { registerAllIdlingResources() onView(withId(R.id.layoutTo)) - .perform(scrollTo()) + .perform(scrollTo()) onView(withId(R.id.editTextRecipientTo)) - .perform(closeSoftKeyboard()) + .perform(closeSoftKeyboard()) val fileWithBiggerSize = TestGeneralUtil.createFileWithGivenSize( - Constants.MAX_TOTAL_ATTACHMENT_SIZE_IN_BYTES + 1024, temporaryFolderRule) + Constants.MAX_TOTAL_ATTACHMENT_SIZE_IN_BYTES + 1024, temporaryFolderRule + ) addAtt(fileWithBiggerSize) - val sizeWarningMsg = getResString(R.string.template_warning_max_total_attachments_size, - FileUtils.byteCountToDisplaySize(Constants.MAX_TOTAL_ATTACHMENT_SIZE_IN_BYTES)) + val sizeWarningMsg = getResString( + R.string.template_warning_max_total_attachments_size, + FileUtils.byteCountToDisplaySize(Constants.MAX_TOTAL_ATTACHMENT_SIZE_IN_BYTES) + ) onView(withText(sizeWarningMsg)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) val fileWithLowerSize = TestGeneralUtil.createFileWithGivenSize( - Constants.MAX_TOTAL_ATTACHMENT_SIZE_IN_BYTES - 1024, temporaryFolderRule) + Constants.MAX_TOTAL_ATTACHMENT_SIZE_IN_BYTES - 1024, temporaryFolderRule + ) addAttAndCheck(fileWithLowerSize) } @@ -329,9 +346,9 @@ class CreateMessageActivityTest : BaseTest() { registerAllIdlingResources() onView(withId(R.id.layoutTo)) - .perform(scrollTo()) + .perform(scrollTo()) onView(withId(R.id.editTextRecipientTo)) - .perform(closeSoftKeyboard()) + .perform(closeSoftKeyboard()) for (att in atts) { addAttAndCheck(att) @@ -345,7 +362,7 @@ class CreateMessageActivityTest : BaseTest() { } onView(withId(R.id.textViewAttachmentName)) - .check(doesNotExist()) + .check(doesNotExist()) } @Test @@ -355,14 +372,14 @@ class CreateMessageActivityTest : BaseTest() { fillInAllFields(TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER) intending(hasComponent(ComponentName(getTargetContext(), ImportPublicKeyActivity::class.java))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) onView(withId(R.id.menuActionSend)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) savePublicKeyInDatabase() onView(withText(R.string.import_their_public_key)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) } @Test @@ -372,11 +389,11 @@ class CreateMessageActivityTest : BaseTest() { fillInAllFields(TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER) onView(withId(R.id.menuActionSend)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(R.string.switch_to_standard_email)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) checkIsDisplayedStandardAttributes() } @@ -386,28 +403,46 @@ class CreateMessageActivityTest : BaseTest() { registerAllIdlingResources() onView(withId(R.id.layoutTo)) - .perform(scrollTo()) + .perform(scrollTo()) onView(withId(R.id.editTextRecipientTo)) - .perform( - typeText(TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER), - closeSoftKeyboard()) + .perform( + typeText(TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER), + closeSoftKeyboard() + ) //move the focus to the next view onView(withId(R.id.editTextEmailMessage)) - .perform(scrollTo(), click(), - typeText(TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER), closeSoftKeyboard()) + .perform( + scrollTo(), click(), + typeText(TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER), closeSoftKeyboard() + ) onView(withId(R.id.menuActionSend)) - .check(matches(isDisplayed())) - .perform(click()) - onView(withText(getResString(R.string.template_remove_recipient, - TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER))) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) + onView( + withText( + getResString( + R.string.template_remove_recipient, + TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER + ) + ) + ) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(R.id.layoutTo)) - .perform(scrollTo()) + .perform(scrollTo()) onView(withId(R.id.editTextRecipientTo)) - .check(matches(isDisplayed())) - .check(matches(withText(not(containsString( - TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER))))) + .check(matches(isDisplayed())) + .check( + matches( + withText( + not( + containsString( + TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER + ) + ) + ) + ) + ) } @Test @@ -419,13 +454,13 @@ class CreateMessageActivityTest : BaseTest() { val result = Intent() result.putExtra(SelectContactsActivity.KEY_EXTRA_PGP_CONTACT, pgpContact.toContactEntity()) intending(hasComponent(ComponentName(getTargetContext(), SelectContactsActivity::class.java))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, result)) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, result)) onView(withId(R.id.menuActionSend)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(R.string.copy_from_other_contact)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) isToastDisplayed(decorView, getResString(R.string.key_successfully_copied)) } @@ -436,21 +471,23 @@ class CreateMessageActivityTest : BaseTest() { openActionBarOverflowOrOptionsMenu(getTargetContext()) onView(withText(R.string.include_public_key)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) val att = EmailUtil.genAttInfoFromPubKey(addPrivateKeyToDatabaseRule.pgpKeyDetails) onView(withText(att?.name)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test fun testSharePubKeyMultiply() { val secondKeyDetails = - PrivateKeysManager.getNodeKeyDetailsFromAssets(TestConstants.DEFAULT_SECOND_KEY_PRV_STRONG) - PrivateKeysManager.saveKeyToDatabase(addAccountToDatabaseRule.account, secondKeyDetails, - TestConstants.DEFAULT_STRONG_PASSWORD, KeyImportDetails.SourceType.EMAIL) + PrivateKeysManager.getNodeKeyDetailsFromAssets(TestConstants.DEFAULT_SECOND_KEY_PRV_STRONG) + PrivateKeysManager.saveKeyToDatabase( + addAccountToDatabaseRule.account, secondKeyDetails, + TestConstants.DEFAULT_STRONG_PASSWORD, KeyImportDetails.SourceType.EMAIL + ) val att = EmailUtil.genAttInfoFromPubKey(secondKeyDetails) activeActivityRule.launch(intent) @@ -458,51 +495,56 @@ class CreateMessageActivityTest : BaseTest() { openActionBarOverflowOrOptionsMenu(getTargetContext()) onView(withText(R.string.include_public_key)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onData(withPubKeyName(att?.name)) - .inAdapterView(withId(R.id.listViewKeys)) - .perform(click()) + .inAdapterView(withId(R.id.listViewKeys)) + .perform(click()) onView(withId(R.id.buttonOk)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(att?.name)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test fun testSharePubKeyNoOwnKeys() { - PrivateKeysManager.deleteKey(addAccountToDatabaseRule.account, - addPrivateKeyToDatabaseRule.keyPath) + PrivateKeysManager.deleteKey( + addAccountToDatabaseRule.account, + addPrivateKeyToDatabaseRule.keyPath + ) val keyDetails = PrivateKeysManager.getNodeKeyDetailsFromAssets( - "pgp/key_testing@flowcrypt.test_keyB_default.asc") - PrivateKeysManager.saveKeyToDatabase(addAccountToDatabaseRule.account, keyDetails, - TestConstants.DEFAULT_PASSWORD, KeyImportDetails.SourceType.EMAIL) + "pgp/key_testing@flowcrypt.test_keyB_default.asc" + ) + PrivateKeysManager.saveKeyToDatabase( + addAccountToDatabaseRule.account, keyDetails, + TestConstants.DEFAULT_PASSWORD, KeyImportDetails.SourceType.EMAIL + ) activeActivityRule.launch(intent) registerAllIdlingResources() openActionBarOverflowOrOptionsMenu(getTargetContext()) onView(withText(R.string.include_public_key)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) val att = EmailUtil.genAttInfoFromPubKey(keyDetails) onView(withText(att?.name)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test fun testShowWarningIfFoundExpiredKey() { val keyDetails = - PrivateKeysManager.getNodeKeyDetailsFromAssets("pgp/expired@flowcrypt.test_pub.asc") + PrivateKeysManager.getNodeKeyDetailsFromAssets("pgp/expired@flowcrypt.test_pub.asc") val contact = keyDetails.primaryPgpContact FlowCryptRoomDatabase.getDatabase(getTargetContext()) - .contactsDao().insert(contact.toContactEntity()) + .contactsDao().insert(contact.toContactEntity()) activeActivityRule.launch(intent) registerAllIdlingResources() @@ -510,31 +552,38 @@ class CreateMessageActivityTest : BaseTest() { fillInAllFields(contact.email) onView(withId(R.id.editTextRecipientTo)) - .check(matches(withChipsBackgroundColor(contact.email, - UIUtil.getColor(getTargetContext(), R.color.orange)))) + .check( + matches( + withChipsBackgroundColor( + contact.email, + UIUtil.getColor(getTargetContext(), R.color.orange) + ) + ) + ) onView(withId(R.id.menuActionSend)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(R.string.warning_one_of_pub_keys_is_expired)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) } @Test fun testKeepPublicKeysFresh() { val keyDetailsFromAssets = - PrivateKeysManager.getNodeKeyDetailsFromAssets("pgp/expired_fixed@flowcrypt.test_expired_pub.asc") + PrivateKeysManager.getNodeKeyDetailsFromAssets("pgp/expired_fixed@flowcrypt.test_expired_pub.asc") val contact = keyDetailsFromAssets.primaryPgpContact val contactsDao = FlowCryptRoomDatabase.getDatabase(getTargetContext()).contactsDao() contactsDao.insert(contact.toContactEntity()) val existedContact = contactsDao.getContactByEmail(contact.email) - ?: throw IllegalArgumentException("Contact not found") + ?: throw IllegalArgumentException("Contact not found") val existedKeyExpiration = PgpKey.parseKeys( - existedContact.publicKey ?: throw IllegalArgumentException("Empty pub key")) - .pgpKeyRingCollection.pgpPublicKeyRingCollection.first().expiration - ?: throw IllegalArgumentException("No expiration date") + existedContact.publicKey ?: throw IllegalArgumentException("Empty pub key") + ) + .pgpKeyRingCollection.pgpPublicKeyRingCollection.first().expiration + ?: throw IllegalArgumentException("No expiration date") Assert.assertTrue(existedKeyExpiration.isBefore(Instant.now())) @@ -544,76 +593,98 @@ class CreateMessageActivityTest : BaseTest() { fillInAllFields(contact.email) onView(withId(R.id.editTextRecipientTo)) - .check(matches(withChipsBackgroundColor(contact.email, - UIUtil.getColor(getTargetContext(), R.color.colorPrimary)))) + .check( + matches( + withChipsBackgroundColor( + contact.email, + UIUtil.getColor(getTargetContext(), R.color.colorPrimary) + ) + ) + ) } private fun checkIsDisplayedEncryptedAttributes() { onView(withId(R.id.underToolbarTextTextView)) - .check(doesNotExist()) + .check(doesNotExist()) onView(withId(R.id.appBarLayout)) - .check(matches(withAppBarLayoutBackgroundColor( - UIUtil.getColor(getTargetContext(), R.color.colorPrimary)))) + .check( + matches( + withAppBarLayoutBackgroundColor( + UIUtil.getColor(getTargetContext(), R.color.colorPrimary) + ) + ) + ) } private fun savePublicKeyInDatabase() { FlowCryptRoomDatabase.getDatabase(getTargetContext()).contactsDao() - .insert(pgpContact.toContactEntity()) + .insert(pgpContact.toContactEntity()) } private fun deleteAtt(att: File) { - onView(allOf(withId(R.id.imageButtonClearAtt), ViewMatchers.withParent( - allOf(withId(R.id.actionButtons), hasSibling(withText(att.name)))))) - .check(matches(isDisplayed())) - .perform(click()) + onView( + allOf( + withId(R.id.imageButtonClearAtt), ViewMatchers.withParent( + allOf(withId(R.id.actionButtons), hasSibling(withText(att.name))) + ) + ) + ) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(att.name)) - .check(doesNotExist()) + .check(doesNotExist()) } private fun addAtt(att: File) { val intent = TestGeneralUtil.genIntentWithPersistedReadPermissionForFile(att) intending( - allOf( - hasAction(Intent.ACTION_CHOOSER), - hasExtra(`is`(Intent.EXTRA_INTENT), - allOf( - hasAction(Intent.ACTION_OPEN_DOCUMENT), - hasType("*/*"), - hasCategories(hasItem(equalTo(Intent.CATEGORY_OPENABLE))) - ) - ) + allOf( + hasAction(Intent.ACTION_CHOOSER), + hasExtra( + `is`(Intent.EXTRA_INTENT), + allOf( + hasAction(Intent.ACTION_OPEN_DOCUMENT), + hasType("*/*"), + hasCategories(hasItem(equalTo(Intent.CATEGORY_OPENABLE))) + ) ) + ) ).respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, intent)) onView(withId(R.id.menuActionAttachFile)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) } private fun addAttAndCheck(att: File) { addAtt(att) onView(withText(att.name)) - .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) + .check(matches(ViewMatchers.withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) } private fun checkIsDisplayedStandardAttributes() { onView(withId(R.id.underToolbarTextTextView)) - .check(matches(isDisplayed())) - .check(matches(withText(R.string.this_message_will_not_be_encrypted))) + .check(matches(isDisplayed())) + .check(matches(withText(R.string.this_message_will_not_be_encrypted))) onView(withId(R.id.appBarLayout)) - .check(matches(withAppBarLayoutBackgroundColor( - UIUtil.getColor(getTargetContext(), R.color.red)))) + .check( + matches( + withAppBarLayoutBackgroundColor( + UIUtil.getColor(getTargetContext(), R.color.red) + ) + ) + ) } private fun fillInAllFields(recipient: String) { onView(withId(R.id.layoutTo)) - .perform(scrollTo()) + .perform(scrollTo()) onView(withId(R.id.editTextRecipientTo)) - .perform(typeText(recipient), closeSoftKeyboard()) + .perform(typeText(recipient), closeSoftKeyboard()) //need to leave focus from 'To' field. move the focus to the next view onView(withId(R.id.editTextEmailSubject)) - .perform(scrollTo(), click(), typeText(EMAIL_SUBJECT), closeSoftKeyboard()) + .perform(scrollTo(), click(), typeText(EMAIL_SUBJECT), closeSoftKeyboard()) onView(withId(R.id.editTextEmailMessage)) - .perform(scrollTo(), typeText(EMAIL_SUBJECT), closeSoftKeyboard()) + .perform(scrollTo(), typeText(EMAIL_SUBJECT), closeSoftKeyboard()) } /** @@ -645,38 +716,43 @@ class CreateMessageActivityTest : BaseTest() { @get:ClassRule @JvmStatic val mockWebServerRule = FlowCryptMockWebServerRule(TestConstants.MOCK_WEB_SERVER_PORT, - object : Dispatcher() { - override fun dispatch(request: RecordedRequest): MockResponse { - if (request.path?.startsWith("/pub", ignoreCase = true) == true) { - val lastSegment = request.requestUrl?.pathSegments?.lastOrNull() - - when { - TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER.equals( - lastSegment, true) -> { - return MockResponse() - .setResponseCode(404) - .setBody(TestGeneralUtil.readResourcesAsString("2.txt")) - } - - TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER.equals( - lastSegment, true) -> { - return MockResponse() - .setResponseCode(200) - .setBody(TestGeneralUtil.readResourcesAsString("3.txt")) - } - - "95FC072E853C9C333C68EDD34B9CA2FBCA5B5FE7".equals(lastSegment, true) -> { - return MockResponse() - .setResponseCode(200) - .setBody(TestGeneralUtil.readFileFromAssetsAsString( - "pgp/expired_fixed@flowcrypt.test_not_expired_pub.asc")) - } + object : Dispatcher() { + override fun dispatch(request: RecordedRequest): MockResponse { + if (request.path?.startsWith("/pub", ignoreCase = true) == true) { + val lastSegment = request.requestUrl?.pathSegments?.lastOrNull() + + when { + TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER.equals( + lastSegment, true + ) -> { + return MockResponse() + .setResponseCode(404) + .setBody(TestGeneralUtil.readResourcesAsString("2.txt")) } - } - return MockResponse().setResponseCode(404) + TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER.equals( + lastSegment, true + ) -> { + return MockResponse() + .setResponseCode(200) + .setBody(TestGeneralUtil.readResourcesAsString("3.txt")) + } + + "95FC072E853C9C333C68EDD34B9CA2FBCA5B5FE7".equals(lastSegment, true) -> { + return MockResponse() + .setResponseCode(200) + .setBody( + TestGeneralUtil.readFileFromAssetsAsString( + "pgp/expired_fixed@flowcrypt.test_not_expired_pub.asc" + ) + ) + } + } } - }) + + return MockResponse().setResponseCode(404) + } + }) @BeforeClass @JvmStatic @@ -686,8 +762,12 @@ class CreateMessageActivityTest : BaseTest() { private fun createFilesForCommonAtts() { for (i in 0 until ATTACHMENTS_COUNT) { - atts.add(TestGeneralUtil.createFileAndFillWithContent(temporaryFolderRule, - "$i.txt", "Text for filling the attached file")) + atts.add( + TestGeneralUtil.createFileAndFillWithContent( + temporaryFolderRule, + "$i.txt", "Text for filling the attached file" + ) + ) } } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateOrImportKeyActivityWithKeysTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateOrImportKeyActivityWithKeysTest.kt index 0d9a075638..f9b939c0cc 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateOrImportKeyActivityWithKeysTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateOrImportKeyActivityWithKeysTest.kt @@ -42,22 +42,37 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class CreateOrImportKeyActivityWithKeysTest : BaseCreateOrImportKeyActivityTest() { override val useIntents: Boolean = true - override val activityScenarioRule = activityScenarioRule(CreateOrImportKeyActivity.newIntent(getTargetContext(), AccountDaoManager.getDefaultAccountDao(), true)) + override val activityScenarioRule = activityScenarioRule( + CreateOrImportKeyActivity.newIntent( + getTargetContext(), + AccountDaoManager.getDefaultAccountDao(), + true + ) + ) @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test fun testClickOnButtonCreateNewKey() { - intending(allOf(hasComponent(ComponentName(getTargetContext(), CreatePrivateKeyActivity::class.java)))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) + intending( + allOf( + hasComponent( + ComponentName( + getTargetContext(), + CreatePrivateKeyActivity::class.java + ) + ) + ) + ) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) onView(withId(R.id.buttonCreateNewKey)) - .check(matches(ViewMatchers.isDisplayed())) - .perform(click()) + .check(matches(ViewMatchers.isDisplayed())) + .perform(click()) Assert.assertTrue(activityScenarioRule.scenario.result.resultCode == Activity.RESULT_OK) } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreatePrivateKeyActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreatePrivateKeyActivityTest.kt index 165d4a2456..3b42a87a14 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreatePrivateKeyActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreatePrivateKeyActivityTest.kt @@ -41,32 +41,35 @@ import org.junit.runner.RunWith class CreatePrivateKeyActivityTest : BasePassphraseActivityTest() { override val activityScenarioRule = activityScenarioRule( - CreatePrivateKeyActivity.newIntent(this@CreatePrivateKeyActivityTest.getTargetContext(), AccountDaoManager.getUserWithMoreThan21Letters()) + CreatePrivateKeyActivity.newIntent( + this@CreatePrivateKeyActivityTest.getTargetContext(), + AccountDaoManager.getUserWithMoreThan21Letters() + ) ) @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test @DependsOnMailServer fun testUseCorrectPassPhrase() { onView(withId(R.id.editTextKeyPassword)) - .check(matches(isDisplayed())) - .perform(replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) + .check(matches(isDisplayed())) + .perform(replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) onView(withId(R.id.buttonSetPassPhrase)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(R.id.editTextKeyPasswordSecond)) - .check(matches(isDisplayed())) - .perform(replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) + .check(matches(isDisplayed())) + .perform(replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) onView(withId(R.id.buttonConfirmPassPhrases)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(R.id.buttonSuccess)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/EmailManagerActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/EmailManagerActivityTest.kt index 9143a0f34a..4664fc8dae 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/EmailManagerActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/EmailManagerActivityTest.kt @@ -48,7 +48,7 @@ import org.junit.Test import org.junit.rules.RuleChain import org.junit.rules.TestRule import org.junit.runner.RunWith -import java.util.* +import java.util.ArrayList /** * @author Denis Bondarenko @@ -67,23 +67,23 @@ class EmailManagerActivityTest : BaseEmailListActivityTest() { @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(AddAccountToDatabaseRule(userWithoutLetters)) - .around(AddAccountToDatabaseRule(userWithMoreThan21LettersAccount)) - .around(AddLabelsToDatabaseRule(userWithMoreThan21LettersAccount, LOCAL_FOLDERS)) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(AddAccountToDatabaseRule(userWithoutLetters)) + .around(AddAccountToDatabaseRule(userWithMoreThan21LettersAccount)) + .around(AddLabelsToDatabaseRule(userWithMoreThan21LettersAccount, LOCAL_FOLDERS)) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test @DependsOnMailServer fun testComposeFloatButton() { onView(withId(R.id.floatActionButtonCompose)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) intended(hasComponent(CreateMessageActivity::class.java.name)) onView(allOf(withText(R.string.compose), withParent(withId(R.id.toolbar)))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test @@ -101,22 +101,22 @@ class EmailManagerActivityTest : BaseEmailListActivityTest() { Thread.sleep(1000) onView(withId(R.id.rVMsgs)) - .perform(RecyclerViewActions.actionOnItemAtPosition(0, scrollTo())) + .perform(RecyclerViewActions.actionOnItemAtPosition(0, scrollTo())) onView(withId(R.id.rVMsgs)) - .check(matches(isDisplayed())) - .perform(swipeDown()) + .check(matches(isDisplayed())) + .perform(swipeDown()) onView(withId(R.id.rVMsgs)) - .check(matches(not(withEmptyRecyclerView()))) - .check(matches(isDisplayed())) + .check(matches(not(withEmptyRecyclerView()))) + .check(matches(isDisplayed())) } @Test @DependsOnMailServer fun testOpenAndSwipeNavigationView() { onView(withId(R.id.drawer_layout)) - .perform(open()) + .perform(open()) onView(withId(R.id.navigationView)) - .perform(swipeUp()) + .perform(swipeUp()) } @Test @@ -133,12 +133,12 @@ class EmailManagerActivityTest : BaseEmailListActivityTest() { @DependsOnMailServer fun testGoToSettingsActivity() { onView(withId(R.id.drawer_layout)) - .perform(open()) + .perform(open()) onView(withId(R.id.navigationView)) - .perform(swipeUp()) + .perform(swipeUp()) onView(withText(R.string.action_settings)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) intended(hasComponent(SettingsActivity::class.java.name)) } @@ -146,71 +146,90 @@ class EmailManagerActivityTest : BaseEmailListActivityTest() { @DependsOnMailServer fun testSwitchLabels() { val menuItem = "Sent" - onView(withId(R.id.toolbar)).check(matches(anyOf( - withToolBarText("INBOX"), - withToolBarText(InstrumentationRegistry.getInstrumentation().targetContext.getString(R - .string.loading))))) + onView(withId(R.id.toolbar)).check( + matches( + anyOf( + withToolBarText("INBOX"), + withToolBarText( + InstrumentationRegistry.getInstrumentation().targetContext.getString( + R.string.loading + ) + ) + ) + ) + ) onView(withId(R.id.drawer_layout)) - .perform(open()) + .perform(open()) onView(withId(R.id.navigationView)) - .perform(navigateToItemWithName(menuItem)) + .perform(navigateToItemWithName(menuItem)) onView(withId(R.id.toolbar)) - .check(matches(withToolBarText(menuItem))) + .check(matches(withToolBarText(menuItem))) } @Test @NotReadyForCI fun testShowAnotherAccounts() { onView(withId(R.id.drawer_layout)) - .perform(open()) + .perform(open()) onView(withId(R.id.textViewActiveUserEmail)) - .check(matches(isDisplayed())).check(matches(withText(userWithMoreThan21LettersAccount.email))) + .check(matches(isDisplayed())) + .check(matches(withText(userWithMoreThan21LettersAccount.email))) onView(withId(R.id.layoutUserDetails)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(userWithoutLetters.email)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } private fun clickLogOut() { onView(withId(R.id.drawer_layout)) - .perform(open()) + .perform(open()) onView(withId(R.id.navigationView)) - .perform(swipeUp()) + .perform(swipeUp()) onView(withText(R.string.log_out)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) } companion object { private val LOCAL_FOLDERS: MutableList private val userWithMoreThan21LettersAccount = AccountDaoManager.getUserWithMoreThan21Letters() private val INBOX_USER_WITH_MORE_THAN_21_LETTERS_ACCOUNT = LocalFolder( - account = userWithMoreThan21LettersAccount.email, - fullName = "INBOX", - folderAlias = "INBOX", - attributes = listOf("\\HasNoChildren"), - isCustom = false) + account = userWithMoreThan21LettersAccount.email, + fullName = "INBOX", + folderAlias = "INBOX", + attributes = listOf("\\HasNoChildren"), + isCustom = false + ) init { LOCAL_FOLDERS = ArrayList() LOCAL_FOLDERS.add(INBOX_USER_WITH_MORE_THAN_21_LETTERS_ACCOUNT) - LOCAL_FOLDERS.add(LocalFolder( + LOCAL_FOLDERS.add( + LocalFolder( account = userWithMoreThan21LettersAccount.email, fullName = "Drafts", folderAlias = "Drafts", - attributes = listOf("\\HasNoChildren", "\\Drafts"))) - LOCAL_FOLDERS.add(LocalFolder( + attributes = listOf("\\HasNoChildren", "\\Drafts") + ) + ) + LOCAL_FOLDERS.add( + LocalFolder( account = userWithMoreThan21LettersAccount.email, fullName = "Sent", folderAlias = "Sent", - attributes = listOf("\\HasNoChildren", "\\Sent"))) - LOCAL_FOLDERS.add(LocalFolder( + attributes = listOf("\\HasNoChildren", "\\Sent") + ) + ) + LOCAL_FOLDERS.add( + LocalFolder( account = userWithMoreThan21LettersAccount.email, fullName = "Junk", folderAlias = "Junk", - attributes = listOf("\\HasNoChildren", "\\Junk"))) + attributes = listOf("\\HasNoChildren", "\\Junk") + ) + ) } } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/HtmlViewFromAssetsRawActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/HtmlViewFromAssetsRawActivityTest.kt index 0598f35bd2..aa92512f2b 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/HtmlViewFromAssetsRawActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/HtmlViewFromAssetsRawActivityTest.kt @@ -38,36 +38,37 @@ import org.junit.runner.RunWith @MediumTest @RunWith(AndroidJUnit4::class) class HtmlViewFromAssetsRawActivityTest : BaseTest() { - override val activeActivityRule = lazyActivityScenarioRule(launchActivity = false) + override val activeActivityRule = + lazyActivityScenarioRule(launchActivity = false) override val activityScenario: ActivityScenario<*>? get() = activeActivityRule.scenario @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(RetryRule.DEFAULT) - .around(activeActivityRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(RetryRule.DEFAULT) + .around(activeActivityRule) + .around(ScreenshotTestRule()) @Test fun testShowPrivacyTitle() { startActivity(InstrumentationRegistry.getInstrumentation().targetContext.getString(R.string.privacy)) onView(allOf(withText(R.string.privacy), withParent(withId(R.id.toolbar)))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test fun testShowTermsTitle() { startActivity(InstrumentationRegistry.getInstrumentation().targetContext.getString(R.string.terms)) onView(allOf(withText(R.string.terms), withParent(withId(R.id.toolbar)))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test fun testShowSecurityTitle() { startActivity(InstrumentationRegistry.getInstrumentation().targetContext.getString(R.string.security)) onView(allOf(withText(R.string.security), withParent(withId(R.id.toolbar)))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } private fun startActivity(title: String) { @@ -79,4 +80,3 @@ class HtmlViewFromAssetsRawActivityTest : BaseTest() { registerAllIdlingResources() } } - diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPgpContactActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPgpContactActivityTest.kt index b99d9b4b72..aaeea05970 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPgpContactActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPgpContactActivityTest.kt @@ -67,61 +67,63 @@ class ImportPgpContactActivityTest : BaseTest() { override val useIntents: Boolean = true override val activityScenarioRule = activityScenarioRule( - intent = ImportPgpContactActivity.newIntent( - context = getTargetContext(), - accountEntity = addAccountToDatabaseRule.account)) + intent = ImportPgpContactActivity.newIntent( + context = getTargetContext(), + accountEntity = addAccountToDatabaseRule.account + ) + ) @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(addAccountToDatabaseRule) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(addAccountToDatabaseRule) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test fun testFetchKeyFromAttesterForExistedUser() { onView(withId(R.id.editTextKeyIdOrEmail)) - .perform( - scrollTo(), - clearText(), - typeText(TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER), - closeSoftKeyboard() - ) + .perform( + scrollTo(), + clearText(), + typeText(TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER), + closeSoftKeyboard() + ) onView(withId(R.id.iBSearchKey)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(containsString(TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test fun testFetchKeyFromAttesterForExistedUserImeAction() { onView(withId(R.id.editTextKeyIdOrEmail)) - .perform( - scrollTo(), - clearText(), - typeText(TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER), - closeSoftKeyboard(), - pressImeActionButton() - ) + .perform( + scrollTo(), + clearText(), + typeText(TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER), + closeSoftKeyboard(), + pressImeActionButton() + ) onView(withText(containsString(TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test fun testFetchKeyFromAttesterForNotExistedUser() { onView(withId(R.id.editTextKeyIdOrEmail)) - .perform( - scrollTo(), - clearText(), - typeText(TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER), - closeSoftKeyboard() - ) + .perform( + scrollTo(), + clearText(), + typeText(TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER), + closeSoftKeyboard() + ) onView(withId(R.id.iBSearchKey)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) //due to realization of MockWebServer I can't produce the same response. isToastDisplayed(decorView, "API error: code = 404, message = ") } @@ -130,32 +132,33 @@ class ImportPgpContactActivityTest : BaseTest() { fun testImportKeyFromFile() { val resultData = TestGeneralUtil.genIntentWithPersistedReadPermissionForFile(fileWithPublicKey) intending( - allOf( - hasAction(Intent.ACTION_CHOOSER), - hasExtra( - `is`(Intent.EXTRA_INTENT), - allOf( - hasAction(Intent.ACTION_OPEN_DOCUMENT), - hasCategories(hasItem(equalTo(Intent.CATEGORY_OPENABLE))), - hasType("*/*")) - ) + allOf( + hasAction(Intent.ACTION_CHOOSER), + hasExtra( + `is`(Intent.EXTRA_INTENT), + allOf( + hasAction(Intent.ACTION_OPEN_DOCUMENT), + hasCategories(hasItem(equalTo(Intent.CATEGORY_OPENABLE))), + hasType("*/*") + ) ) + ) ).respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)) onView(withId(R.id.buttonLoadFromFile)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(containsString(TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test fun testImportKeyFromClipboard() { addTextToClipboard("public key", publicKey) onView(withId(R.id.buttonLoadFromClipboard)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(containsString(TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } companion object { @@ -165,40 +168,44 @@ class ImportPgpContactActivityTest : BaseTest() { @get:ClassRule @JvmStatic val mockWebServerRule = FlowCryptMockWebServerRule(TestConstants.MOCK_WEB_SERVER_PORT, - object : Dispatcher() { - override fun dispatch(request: RecordedRequest): MockResponse { - if (request.path?.startsWith("/pub", ignoreCase = true) == true) { - val lastSegment = request.requestUrl?.pathSegments?.lastOrNull() - - when { - TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER.equals( - lastSegment, true) -> { - return MockResponse() - .setStatus("HTTP/1.1 404 Not Found") - .setBody(TestGeneralUtil.readResourcesAsString("2.txt")) - } - - TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER.equals( - lastSegment, true) -> { - return MockResponse() - .setResponseCode(200) - .setBody(TestGeneralUtil.readResourcesAsString("3.txt")) - } + object : Dispatcher() { + override fun dispatch(request: RecordedRequest): MockResponse { + if (request.path?.startsWith("/pub", ignoreCase = true) == true) { + val lastSegment = request.requestUrl?.pathSegments?.lastOrNull() + + when { + TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER.equals( + lastSegment, true + ) -> { + return MockResponse() + .setStatus("HTTP/1.1 404 Not Found") + .setBody(TestGeneralUtil.readResourcesAsString("2.txt")) } - } - return MockResponse().setResponseCode(404) + TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER.equals( + lastSegment, true + ) -> { + return MockResponse() + .setResponseCode(200) + .setBody(TestGeneralUtil.readResourcesAsString("3.txt")) + } + } } - }) + + return MockResponse().setResponseCode(404) + } + }) @BeforeClass @JvmStatic fun createResources() { publicKey = TestGeneralUtil.readFileFromAssetsAsString( - "pgp/" + TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER + "-pub.asc") + "pgp/" + TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER + "-pub.asc" + ) fileWithPublicKey = TestGeneralUtil.createFileAndFillWithContent( - fileName = TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER + "_pub.asc", - fileText = publicKey) + fileName = TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER + "_pub.asc", + fileText = publicKey + ) } @AfterClass diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPrivateKeyActivityFromSettingsTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPrivateKeyActivityFromSettingsTest.kt index 194b07ce82..f7e8097c68 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPrivateKeyActivityFromSettingsTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPrivateKeyActivityFromSettingsTest.kt @@ -63,22 +63,24 @@ class ImportPrivateKeyActivityFromSettingsTest : BaseTest() { override val useIntents: Boolean = true override val activityScenarioRule = activityScenarioRule( - intent = ImportPrivateKeyActivity.getIntent( - context = getTargetContext(), - accountEntity = addAccountToDatabaseRule.account, - isSyncEnabled = true, - title = getTargetContext().getString(R.string.import_private_key), - throwErrorIfDuplicateFoundEnabled = true, - isSubmittingPubKeysEnabled = false, - cls = ImportPrivateKeyActivity::class.java)) + intent = ImportPrivateKeyActivity.getIntent( + context = getTargetContext(), + accountEntity = addAccountToDatabaseRule.account, + isSyncEnabled = true, + title = getTargetContext().getString(R.string.import_private_key), + throwErrorIfDuplicateFoundEnabled = true, + isSubmittingPubKeysEnabled = false, + cls = ImportPrivateKeyActivity::class.java + ) + ) @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(addAccountToDatabaseRule) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(addAccountToDatabaseRule) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test @NotReadyForCI @@ -86,8 +88,8 @@ class ImportPrivateKeyActivityFromSettingsTest : BaseTest() { useIntentionFromRunCheckKeysActivity() onView(withId(R.id.buttonImportBackup)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) Assert.assertTrue(activityScenarioRule.scenario.result.resultCode == Activity.RESULT_OK) } @@ -98,8 +100,8 @@ class ImportPrivateKeyActivityFromSettingsTest : BaseTest() { useIntentionFromRunCheckKeysActivity() onView(withId(R.id.buttonLoadFromFile)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) Assert.assertTrue(activityScenarioRule.scenario.result.resultCode == Activity.RESULT_OK) } @@ -109,9 +111,12 @@ class ImportPrivateKeyActivityFromSettingsTest : BaseTest() { useIntentionToRunActivityToSelectFile(fileWithoutPrivateKey) onView(withId(R.id.buttonLoadFromFile)) - .check(matches(isDisplayed())) - .perform(click()) - isDialogWithTextDisplayed(decorView, getResString(R.string.file_has_wrong_pgp_structure, getResString(R.string.private_))) + .check(matches(isDisplayed())) + .perform(click()) + isDialogWithTextDisplayed( + decorView, + getResString(R.string.file_has_wrong_pgp_structure, getResString(R.string.private_)) + ) } @Test @@ -121,8 +126,8 @@ class ImportPrivateKeyActivityFromSettingsTest : BaseTest() { addTextToClipboard("private key", privateKey) onView(withId(R.id.buttonLoadFromClipboard)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) Assert.assertTrue(activityScenarioRule.scenario.result.resultCode == Activity.RESULT_OK) } @@ -131,16 +136,29 @@ class ImportPrivateKeyActivityFromSettingsTest : BaseTest() { fun testShowErrorWhenImportKeyFromClipboard() { addTextToClipboard("not private key", SOME_TEXT) onView(withId(R.id.buttonLoadFromClipboard)) - .check(matches(isDisplayed())) - .perform(click()) - isDialogWithTextDisplayed(decorView, getResString(R.string.clipboard_has_wrong_structure, getResString(R.string.private_))) + .check(matches(isDisplayed())) + .perform(click()) + isDialogWithTextDisplayed( + decorView, + getResString(R.string.clipboard_has_wrong_structure, getResString(R.string.private_)) + ) } private fun useIntentionToRunActivityToSelectFile(file: File) { val resultData = TestGeneralUtil.genIntentWithPersistedReadPermissionForFile(file) - intending(allOf(hasAction(Intent.ACTION_CHOOSER), hasExtra(`is`(Intent.EXTRA_INTENT), allOf(hasAction(Intent - .ACTION_OPEN_DOCUMENT), hasCategories(hasItem(equalTo(Intent.CATEGORY_OPENABLE))), hasType("*/*"))))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)) + intending( + allOf( + hasAction(Intent.ACTION_CHOOSER), hasExtra( + `is`(Intent.EXTRA_INTENT), allOf( + hasAction( + Intent + .ACTION_OPEN_DOCUMENT + ), hasCategories(hasItem(equalTo(Intent.CATEGORY_OPENABLE))), hasType("*/*") + ) + ) + ) + ) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)) } @@ -151,7 +169,7 @@ class ImportPrivateKeyActivityFromSettingsTest : BaseTest() { intent.putExtra(CheckKeysActivity.KEY_EXTRA_UNLOCKED_PRIVATE_KEYS, list) intending(hasComponent(ComponentName(getTargetContext(), CheckKeysActivity::class.java))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, intent)) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, intent)) } companion object { @@ -160,7 +178,7 @@ class ImportPrivateKeyActivityFromSettingsTest : BaseTest() { private lateinit var fileWithoutPrivateKey: File private lateinit var privateKey: String private var keyDetails = - PrivateKeysManager.getNodeKeyDetailsFromAssets("pgp/attested_user@flowcrypt.test_prv_default_strong.asc") + PrivateKeysManager.getNodeKeyDetailsFromAssets("pgp/attested_user@flowcrypt.test_prv_default_strong.asc") @BeforeClass @JvmStatic @@ -169,9 +187,11 @@ class ImportPrivateKeyActivityFromSettingsTest : BaseTest() { keyDetails.passphraseType = KeyEntity.PassphraseType.DATABASE privateKey = keyDetails.privateKey!! fileWithPrivateKey = TestGeneralUtil.createFileAndFillWithContent( - TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER + "_sec.asc", privateKey) + TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER + "_sec.asc", privateKey + ) fileWithoutPrivateKey = TestGeneralUtil.createFileAndFillWithContent( - TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER + ".txt", SOME_TEXT) + TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER + ".txt", SOME_TEXT + ) } @AfterClass diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPrivateKeyActivityNoPubOrgRulesTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPrivateKeyActivityNoPubOrgRulesTest.kt index 5e6e088b14..67f582fa7c 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPrivateKeyActivityNoPubOrgRulesTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPrivateKeyActivityNoPubOrgRulesTest.kt @@ -59,20 +59,22 @@ class ImportPrivateKeyActivityNoPubOrgRulesTest : BaseTest() { override val useIntents: Boolean = true override val activityScenarioRule = activityScenarioRule( - intent = ImportPrivateKeyActivity.getIntent( - context = getTargetContext(), - accountEntity = account, - isSyncEnabled = false, - title = getTargetContext().getString(R.string.import_private_key), - throwErrorIfDuplicateFoundEnabled = true, - cls = ImportPrivateKeyActivity::class.java)) + intent = ImportPrivateKeyActivity.getIntent( + context = getTargetContext(), + accountEntity = account, + isSyncEnabled = false, + title = getTargetContext().getString(R.string.import_private_key), + throwErrorIfDuplicateFoundEnabled = true, + cls = ImportPrivateKeyActivity::class.java + ) + ) @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test fun testErrorWhenImportingKeyFromFile() { @@ -80,8 +82,8 @@ class ImportPrivateKeyActivityNoPubOrgRulesTest : BaseTest() { addTextToClipboard("private key", privateKey) Espresso.onView(ViewMatchers.withId(R.id.buttonLoadFromClipboard)) - .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) - .perform(ViewActions.click()) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + .perform(ViewActions.click()) isDialogWithTextDisplayed(decorView, ERROR_MESSAGE_FROM_ATTESTER) } @@ -92,16 +94,24 @@ class ImportPrivateKeyActivityNoPubOrgRulesTest : BaseTest() { list.add(keyDetails) intent.putExtra(CheckKeysActivity.KEY_EXTRA_UNLOCKED_PRIVATE_KEYS, list) - Intents.intending(IntentMatchers.hasComponent(ComponentName(getTargetContext(), CheckKeysActivity::class.java))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, intent)) + Intents.intending( + IntentMatchers.hasComponent( + ComponentName( + getTargetContext(), + CheckKeysActivity::class.java + ) + ) + ) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, intent)) } companion object { - private const val ERROR_MESSAGE_FROM_ATTESTER = "Could not find LDAP pubkey on a LDAP-only domain for email no.pub@org-rules-test.flowcrypt.com on server keys.flowcrypt.com" + private const val ERROR_MESSAGE_FROM_ATTESTER = + "Could not find LDAP pubkey on a LDAP-only domain for email no.pub@org-rules-test.flowcrypt.com on server keys.flowcrypt.com" private lateinit var privateKey: String private var keyDetails = - PrivateKeysManager.getNodeKeyDetailsFromAssets("pgp/no.pub@org-rules-test.flowcrypt.test_orv_default.asc") + PrivateKeysManager.getNodeKeyDetailsFromAssets("pgp/no.pub@org-rules-test.flowcrypt.test_orv_default.asc") @BeforeClass @JvmStatic @@ -112,24 +122,36 @@ class ImportPrivateKeyActivityNoPubOrgRulesTest : BaseTest() { @get:ClassRule @JvmStatic - val mockWebServerRule = FlowCryptMockWebServerRule(TestConstants.MOCK_WEB_SERVER_PORT, object : Dispatcher() { - override fun dispatch(request: RecordedRequest): MockResponse { - val gson = ApiHelper.getInstance(InstrumentationRegistry.getInstrumentation().targetContext).gson - if (request.path.equals("/initial/legacy_submit")) { - val requestModel = gson.fromJson(InputStreamReader(request.body.inputStream()), InitialLegacySubmitModel::class.java) - - when { - requestModel.email.equals("no.pub@org-rules-test.flowcrypt.com", true) -> { - val model = gson.fromJson( - InputStreamReader(ByteArrayInputStream(TestGeneralUtil.readObjectFromResourcesAsByteArray("4.json"))), - InitialLegacySubmitResponse::class.java) - return MockResponse().setResponseCode(200).setBody(gson.toJson(model)) + val mockWebServerRule = + FlowCryptMockWebServerRule(TestConstants.MOCK_WEB_SERVER_PORT, object : Dispatcher() { + override fun dispatch(request: RecordedRequest): MockResponse { + val gson = + ApiHelper.getInstance(InstrumentationRegistry.getInstrumentation().targetContext).gson + if (request.path.equals("/initial/legacy_submit")) { + val requestModel = gson.fromJson( + InputStreamReader(request.body.inputStream()), + InitialLegacySubmitModel::class.java + ) + + when { + requestModel.email.equals("no.pub@org-rules-test.flowcrypt.com", true) -> { + val model = gson.fromJson( + InputStreamReader( + ByteArrayInputStream( + TestGeneralUtil.readObjectFromResourcesAsByteArray( + "4.json" + ) + ) + ), + InitialLegacySubmitResponse::class.java + ) + return MockResponse().setResponseCode(200).setBody(gson.toJson(model)) + } } } - } - return MockResponse().setResponseCode(404) - } - }) + return MockResponse().setResponseCode(404) + } + }) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivityTest.kt index 19e2366679..74d413cd29 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivityTest.kt @@ -56,51 +56,79 @@ import java.io.File class ImportPublicKeyActivityTest : BaseTest() { override val useIntents: Boolean = true override val activityScenarioRule = activityScenarioRule( - intent = Intent(getTargetContext(), ImportPublicKeyActivity::class.java).apply { - putExtra(BaseImportKeyActivity.KEY_EXTRA_IS_SYNC_ENABLE, true) - putExtra(BaseImportKeyActivity.KEY_EXTRA_TITLE, getResString(R.string.import_public_key)) - putExtra(BaseImportKeyActivity.KEY_EXTRA_IS_THROW_ERROR_IF_DUPLICATE_FOUND, false) - putExtra(ImportPublicKeyActivity.KEY_EXTRA_PGP_CONTACT, PgpContact(TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER)) - }) + intent = Intent(getTargetContext(), ImportPublicKeyActivity::class.java).apply { + putExtra(BaseImportKeyActivity.KEY_EXTRA_IS_SYNC_ENABLE, true) + putExtra(BaseImportKeyActivity.KEY_EXTRA_TITLE, getResString(R.string.import_public_key)) + putExtra(BaseImportKeyActivity.KEY_EXTRA_IS_THROW_ERROR_IF_DUPLICATE_FOUND, false) + putExtra( + ImportPublicKeyActivity.KEY_EXTRA_PGP_CONTACT, + PgpContact(TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER) + ) + }) @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(AddAccountToDatabaseRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(AddAccountToDatabaseRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test fun testImportKeyFromFile() { val resultData = TestGeneralUtil.genIntentWithPersistedReadPermissionForFile(fileWithPublicKey) - intending(allOf(hasAction(Intent.ACTION_CHOOSER), hasExtra(`is`(Intent.EXTRA_INTENT), allOf(hasAction(Intent - .ACTION_OPEN_DOCUMENT), hasCategories(hasItem(equalTo(Intent.CATEGORY_OPENABLE))), hasType("*/*"))))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)) + intending( + allOf( + hasAction(Intent.ACTION_CHOOSER), + hasExtra( + `is`(Intent.EXTRA_INTENT), + allOf( + hasAction(Intent.ACTION_OPEN_DOCUMENT), + hasCategories(hasItem(equalTo(Intent.CATEGORY_OPENABLE))), + hasType("*/*") + ) + ) + ) + ) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)) onView(withId(R.id.buttonLoadFromFile)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) Assert.assertTrue(activityScenarioRule.scenario.result.resultCode == Activity.RESULT_OK) } @Test fun testShowErrorWhenImportingKeyFromFile() { - val resultData = TestGeneralUtil.genIntentWithPersistedReadPermissionForFile(fileWithoutPublicKey) - intending(allOf(hasAction(Intent.ACTION_CHOOSER), hasExtra(`is`(Intent.EXTRA_INTENT), allOf(hasAction(Intent - .ACTION_OPEN_DOCUMENT), hasCategories(hasItem(equalTo(Intent.CATEGORY_OPENABLE))), hasType("*/*"))))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)) + val resultData = + TestGeneralUtil.genIntentWithPersistedReadPermissionForFile(fileWithoutPublicKey) + intending( + allOf( + hasAction(Intent.ACTION_CHOOSER), hasExtra( + `is`(Intent.EXTRA_INTENT), allOf( + hasAction( + Intent + .ACTION_OPEN_DOCUMENT + ), hasCategories(hasItem(equalTo(Intent.CATEGORY_OPENABLE))), hasType("*/*") + ) + ) + ) + ) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)) onView(withId(R.id.buttonLoadFromFile)) - .check(matches(isDisplayed())) - .perform(click()) - isDialogWithTextDisplayed(decorView, getResString(R.string.file_has_wrong_pgp_structure, getResString(R.string.public_))) + .check(matches(isDisplayed())) + .perform(click()) + isDialogWithTextDisplayed( + decorView, + getResString(R.string.file_has_wrong_pgp_structure, getResString(R.string.public_)) + ) } @Test fun testImportKeyFromClipboard() { addTextToClipboard("public key", publicKey) onView(withId(R.id.buttonLoadFromClipboard)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) Assert.assertTrue(activityScenarioRule.scenario.result.resultCode == Activity.RESULT_OK) } @@ -108,9 +136,12 @@ class ImportPublicKeyActivityTest : BaseTest() { fun testShowErrorWhenImportKeyFromClipboard() { addTextToClipboard("not public key", SOME_TEXT) onView(withId(R.id.buttonLoadFromClipboard)) - .check(matches(isDisplayed())) - .perform(click()) - isDialogWithTextDisplayed(decorView, getResString(R.string.clipboard_has_wrong_structure, getResString(R.string.public_))) + .check(matches(isDisplayed())) + .perform(click()) + isDialogWithTextDisplayed( + decorView, + getResString(R.string.clipboard_has_wrong_structure, getResString(R.string.public_)) + ) } companion object { @@ -123,11 +154,14 @@ class ImportPublicKeyActivityTest : BaseTest() { @JvmStatic fun createResources() { publicKey = TestGeneralUtil.readFileFromAssetsAsString( - "pgp/not_attested_user@flowcrypt.test-pub.asc") + "pgp/not_attested_user@flowcrypt.test-pub.asc" + ) fileWithPublicKey = TestGeneralUtil.createFileAndFillWithContent( - TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER + "_pub.asc", publicKey) + TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER + "_pub.asc", publicKey + ) fileWithoutPublicKey = TestGeneralUtil.createFileAndFillWithContent( - TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER + ".txt", SOME_TEXT) + TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER + ".txt", SOME_TEXT + ) } @AfterClass diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/KeysSettingsActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/KeysSettingsActivityTest.kt index f1eaf9dede..de29a637bd 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/KeysSettingsActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/KeysSettingsActivityTest.kt @@ -59,7 +59,8 @@ import org.junit.rules.RuleChain import org.junit.rules.TestRule import org.junit.runner.RunWith import java.io.File -import java.util.* +import java.util.ArrayList +import java.util.Date /** * @author Denis Bondarenko @@ -79,12 +80,12 @@ class KeysSettingsActivityTest : BaseTest() { @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(addAccountToDatabaseRule) - .around(addPrivateKeyToDatabaseRule) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(addAccountToDatabaseRule) + .around(addPrivateKeyToDatabaseRule) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Before fun waitData() { @@ -96,30 +97,31 @@ class KeysSettingsActivityTest : BaseTest() { @Test fun testAddNewKeys() { intending(hasComponent(ComponentName(getTargetContext(), ImportPrivateKeyActivity::class.java))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) - val details = PrivateKeysManager.getNodeKeyDetailsFromAssets("pgp/default@flowcrypt.test_secondKey_prv_default.asc") + val details = + PrivateKeysManager.getNodeKeyDetailsFromAssets("pgp/default@flowcrypt.test_secondKey_prv_default.asc") PrivateKeysManager.saveKeyToDatabase( - accountEntity = addAccountToDatabaseRule.account, - pgpKeyDetails = details, - passphrase = TestConstants.DEFAULT_PASSWORD, - sourceType = KeyImportDetails.SourceType.EMAIL + accountEntity = addAccountToDatabaseRule.account, + pgpKeyDetails = details, + passphrase = TestConstants.DEFAULT_PASSWORD, + sourceType = KeyImportDetails.SourceType.EMAIL ) onView(withId(R.id.floatActionButtonAddKey)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(R.id.recyclerViewKeys)) - .check(matches(isDisplayed())) - .check(matches(withRecyclerViewItemCount(2))) + .check(matches(isDisplayed())) + .check(matches(withRecyclerViewItemCount(2))) } @Test fun testKeyExists() { onView(withId(R.id.recyclerViewKeys)) - .check(matches(not(withEmptyRecyclerView()))).check(matches(isDisplayed())) + .check(matches(not(withEmptyRecyclerView()))).check(matches(isDisplayed())) onView(withId(R.id.emptyView)) - .check(matches(not(isDisplayed()))) + .check(matches(not(isDisplayed()))) } @Test @@ -132,8 +134,8 @@ class KeysSettingsActivityTest : BaseTest() { selectFirstKey() val keyDetails = addPrivateKeyToDatabaseRule.pgpKeyDetails onView(withId(R.id.btnShowPubKey)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(keyDetails.publicKey)) } @@ -142,8 +144,8 @@ class KeysSettingsActivityTest : BaseTest() { selectFirstKey() val details = addPrivateKeyToDatabaseRule.pgpKeyDetails onView(withId(R.id.btnCopyToClipboard)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) isToastDisplayed(decorView, getResString(R.string.copied)) UiThreadStatement.runOnUiThread { checkClipboardText(details.publicKey) } } @@ -153,8 +155,8 @@ class KeysSettingsActivityTest : BaseTest() { fun testKeyDetailsShowPrivateKey() { selectFirstKey() onView(withId(R.id.btnShowPrKey)) - .perform(scrollTo()) - .perform(click()) + .perform(scrollTo()) + .perform(click()) isToastDisplayed(decorView, getResString(R.string.see_backups_to_save_your_private_keys)) } @@ -164,15 +166,35 @@ class KeysSettingsActivityTest : BaseTest() { val details = addPrivateKeyToDatabaseRule.pgpKeyDetails onView(withId(R.id.textViewFingerprint)) - .check(matches(withText(getHtmlString(getResString(R.string.template_fingerprint, - GeneralUtil.doSectionsInText(" ", details.fingerprint, 4)!!))))) + .check( + matches( + withText( + getHtmlString( + getResString( + R.string.template_fingerprint, + GeneralUtil.doSectionsInText(" ", details.fingerprint, 4)!! + ) + ) + ) + ) + ) onView(withId(R.id.textViewDate)) - .check(matches(withText(getHtmlString(getResString(R.string.template_date, - DateFormat.getMediumDateFormat(getTargetContext()).format(Date(details.created))))))) + .check( + matches( + withText( + getHtmlString( + getResString( + R.string.template_date, + DateFormat.getMediumDateFormat(getTargetContext()).format(Date(details.created)) + ) + ) + ) + ) + ) onView(withId(R.id.tVPassPhraseVerification)) - .check(matches(withText(getResString(R.string.stored_pass_phrase_matched)))) + .check(matches(withText(getResString(R.string.stored_pass_phrase_matched)))) val emails = ArrayList() @@ -181,26 +203,27 @@ class KeysSettingsActivityTest : BaseTest() { } onView(withId(R.id.textViewUsers)) - .check(matches(withText(getResString(R.string.template_users, TextUtils.join(", ", emails))))) + .check(matches(withText(getResString(R.string.template_users, TextUtils.join(", ", emails))))) } @Test fun testKeyDetailsTestPassPhraseMismatch() { val details = PrivateKeysManager.getNodeKeyDetailsFromAssets( - "pgp/default@flowcrypt.test_secondKey_prv_default.asc") + "pgp/default@flowcrypt.test_secondKey_prv_default.asc" + ) PrivateKeysManager.saveKeyToDatabase( - accountEntity = addAccountToDatabaseRule.account, - pgpKeyDetails = details, - passphrase = "wrong passphrase", - sourceType = KeyImportDetails.SourceType.EMAIL + accountEntity = addAccountToDatabaseRule.account, + pgpKeyDetails = details, + passphrase = "wrong passphrase", + sourceType = KeyImportDetails.SourceType.EMAIL ) onView(withId(R.id.recyclerViewKeys)) - .perform(RecyclerViewActions.actionOnItemAtPosition(0, click())) + .perform(RecyclerViewActions.actionOnItemAtPosition(0, click())) onView(withId(R.id.tVPassPhraseVerification)) - .check(matches(withText(getResString(R.string.stored_pass_phrase_mismatch)))) - .check(matches(hasTextColor(R.color.red))) + .check(matches(withText(getResString(R.string.stored_pass_phrase_mismatch)))) + .check(matches(hasTextColor(R.color.red))) } @Test @@ -209,29 +232,36 @@ class KeysSettingsActivityTest : BaseTest() { val details = addPrivateKeyToDatabaseRule.pgpKeyDetails val file = - File(getTargetContext().getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), - "0x" + details.fingerprint + ".asc") + File( + getTargetContext().getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), + "0x" + details.fingerprint + ".asc" + ) if (file.exists()) { file.delete() } val resultData = Intent() - resultData.data = FileProvider.getUriForFile(getTargetContext(), Constants.FILE_PROVIDER_AUTHORITY, file) + resultData.data = + FileProvider.getUriForFile(getTargetContext(), Constants.FILE_PROVIDER_AUTHORITY, file) - intending(allOf(hasAction(Intent.ACTION_CREATE_DOCUMENT), + intending( + allOf( + hasAction(Intent.ACTION_CREATE_DOCUMENT), hasCategories(hasItem(equalTo(Intent.CATEGORY_OPENABLE))), - hasType(Constants.MIME_TYPE_PGP_KEY))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)) + hasType(Constants.MIME_TYPE_PGP_KEY) + ) + ) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)) onView(withId(R.id.btnSaveToFile)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) isToastDisplayed(decorView, getResString(R.string.saved)) } private fun selectFirstKey() { onView(withId(R.id.recyclerViewKeys)) - .perform(RecyclerViewActions.actionOnItemAtPosition(0, click())) + .perform(RecyclerViewActions.actionOnItemAtPosition(0, click())) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/LegalSettingsActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/LegalSettingsActivityTest.kt index 3508b1d794..b829f60bc8 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/LegalSettingsActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/LegalSettingsActivityTest.kt @@ -44,26 +44,27 @@ class LegalSettingsActivityTest : BaseTest() { @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(AddAccountToDatabaseRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(AddAccountToDatabaseRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) private val titleNames: Array = arrayOf( - getResString(R.string.privacy), - getResString(R.string.terms), - getResString(R.string.licence), - getResString(R.string.sources)) + getResString(R.string.privacy), + getResString(R.string.terms), + getResString(R.string.licence), + getResString(R.string.sources) + ) @Test fun testClickToTitleViewPager() { for (titleName in titleNames) { onView(allOf(withParent(withParent(withParent(withId(R.id.tabLayout)))), withText(titleName))) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(allOf(withParent(withParent(withParent(withId(R.id.tabLayout)))), withText(titleName))) - .check(matches(isDisplayed())).check(matches(isSelected())) + .check(matches(isDisplayed())).check(matches(isSelected())) } } @@ -74,12 +75,22 @@ class LegalSettingsActivityTest : BaseTest() { @Test fun testSwipeInViewPager() { - onView(allOf(withParent(withParent(withParent(withId(R.id.tabLayout)))), withText(titleNames[0]))) - .check(matches(isDisplayed())).check(matches(isSelected())) + onView( + allOf( + withParent(withParent(withParent(withId(R.id.tabLayout)))), + withText(titleNames[0]) + ) + ) + .check(matches(isDisplayed())).check(matches(isSelected())) for (i in 1 until titleNames.size) { onView(withId(R.id.viewPager)).perform(swipeLeft()) - onView(allOf(withParent(withParent(withParent(withId(R.id.tabLayout)))), withText(titleNames[i]))) - .check(matches(isDisplayed())).check(matches(isSelected())) + onView( + allOf( + withParent(withParent(withParent(withId(R.id.tabLayout)))), + withText(titleNames[i]) + ) + ) + .check(matches(isDisplayed())).check(matches(isSelected())) } } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/MessageDetailsActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/MessageDetailsActivityTest.kt index 828f09ddfd..88aaf378a5 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/MessageDetailsActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/MessageDetailsActivityTest.kt @@ -88,32 +88,43 @@ import java.util.concurrent.TimeUnit @RunWith(AndroidJUnit4::class) class MessageDetailsActivityTest : BaseTest() { override val useIntents: Boolean = true - override val activeActivityRule = lazyActivityScenarioRule(launchActivity = false) + override val activeActivityRule = + lazyActivityScenarioRule(launchActivity = false) override val activityScenario: ActivityScenario<*>? get() = activeActivityRule.scenario private val addAccountToDatabaseRule = AddAccountToDatabaseRule() private var idlingForWebView: IdlingResource? = null - private val simpleAttInfo = TestGeneralUtil.getObjectFromJson("messages/attachments/simple_att.json", AttachmentInfo::class.java) - private val encryptedAttInfo = TestGeneralUtil.getObjectFromJson("messages/attachments/encrypted_att.json", AttachmentInfo::class.java) - private val pubKeyAttInfo = TestGeneralUtil.getObjectFromJson("messages/attachments/pub_key.json", AttachmentInfo::class.java) + private val simpleAttInfo = TestGeneralUtil.getObjectFromJson( + "messages/attachments/simple_att.json", + AttachmentInfo::class.java + ) + private val encryptedAttInfo = TestGeneralUtil.getObjectFromJson( + "messages/attachments/encrypted_att.json", + AttachmentInfo::class.java + ) + private val pubKeyAttInfo = TestGeneralUtil.getObjectFromJson( + "messages/attachments/pub_key.json", + AttachmentInfo::class.java + ) @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(addAccountToDatabaseRule) - .around(AddPrivateKeyToDatabaseRule()) - .around(RetryRule.DEFAULT) - .around(activeActivityRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(addAccountToDatabaseRule) + .around(AddPrivateKeyToDatabaseRule()) + .around(RetryRule.DEFAULT) + .around(activeActivityRule) + .around(ScreenshotTestRule()) private val localFolder: LocalFolder = LocalFolder( - addAccountToDatabaseRule.account.email, - fullName = "INBOX", - folderAlias = "INBOX", - msgCount = 1, - attributes = listOf("\\HasNoChildren")) + addAccountToDatabaseRule.account.email, + fullName = "INBOX", + folderAlias = "INBOX", + msgCount = 1, + attributes = listOf("\\HasNoChildren") + ) @After fun unregisterDecryptionIdling() { @@ -124,8 +135,8 @@ class MessageDetailsActivityTest : BaseTest() { fun testReplyButton() { testStandardMsgPlaintext() onView(withId(R.id.layoutReplyButton)) - .check(matches(isDisplayed())) - .perform(scrollTo(), click()) + .check(matches(isDisplayed())) + .perform(scrollTo(), click()) intended(hasComponent(CreateMessageActivity::class.java.name)) } @@ -138,8 +149,8 @@ class MessageDetailsActivityTest : BaseTest() { fun testReplyAllButton() { testStandardMsgPlaintext() onView(withId(R.id.layoutReplyAllButton)) - .check(matches(isDisplayed())) - .perform(scrollTo(), click()) + .check(matches(isDisplayed())) + .perform(scrollTo(), click()) intended(hasComponent(CreateMessageActivity::class.java.name)) } @@ -147,8 +158,8 @@ class MessageDetailsActivityTest : BaseTest() { fun testFwdButton() { testStandardMsgPlaintext() onView(withId(R.id.layoutFwdButton)) - .check(matches(isDisplayed())) - .perform(scrollTo(), click()) + .check(matches(isDisplayed())) + .perform(scrollTo(), click()) intended(hasComponent(CreateMessageActivity::class.java.name)) } @@ -159,22 +170,34 @@ class MessageDetailsActivityTest : BaseTest() { @Test fun testStandardMsgPlaintext() { - baseCheck(getMsgInfo("messages/info/standard_msg_info_plaintext.json", - "messages/mime/standard_msg_info_plaintext.txt")) + baseCheck( + getMsgInfo( + "messages/info/standard_msg_info_plaintext.json", + "messages/mime/standard_msg_info_plaintext.txt" + ) + ) onView(withId(R.id.tVTo)) - .check(matches(withText(getResString(R.string.to_receiver, getResString(R.string.me))))) + .check(matches(withText(getResString(R.string.to_receiver, getResString(R.string.me))))) } @Test fun testStandardMsgPlaintextWithOneAttachment() { - baseCheckWithAtt(getMsgInfo("messages/info/standard_msg_info_plaintext_with_one_att.json", - "messages/mime/standard_msg_info_plaintext_with_one_att.txt", simpleAttInfo), simpleAttInfo) + baseCheckWithAtt( + getMsgInfo( + "messages/info/standard_msg_info_plaintext_with_one_att.json", + "messages/mime/standard_msg_info_plaintext_with_one_att.txt", simpleAttInfo + ), simpleAttInfo + ) } @Test fun testEncryptedMsgPlaintext() { - baseCheck(getMsgInfo("messages/info/encrypted_msg_info_text.json", - "messages/mime/encrypted_msg_info_plain_text.txt")) + baseCheck( + getMsgInfo( + "messages/info/encrypted_msg_info_text.json", + "messages/mime/encrypted_msg_info_plain_text.txt" + ) + ) } @Test @@ -182,52 +205,71 @@ class MessageDetailsActivityTest : BaseTest() { //don't enable this one on CI. It takes too long fun testEncryptedBigInlineAtt() { IdlingPolicies.setIdlingResourceTimeout(3, TimeUnit.MINUTES) - baseCheck(getMsgInfo("messages/info/encrypted_msg_big_inline_att.json", - "messages/mime/encrypted_msg_big_inline_att.txt")) + baseCheck( + getMsgInfo( + "messages/info/encrypted_msg_big_inline_att.json", + "messages/mime/encrypted_msg_big_inline_att.txt" + ) + ) } @Test fun testMissingKeyErrorImportKey() { - testMissingKey(getMsgInfo("messages/info/encrypted_msg_info_text_with_missing_key.json", - "messages/mime/encrypted_msg_info_text_with_missing_key.txt")) + testMissingKey( + getMsgInfo( + "messages/info/encrypted_msg_info_text_with_missing_key.json", + "messages/mime/encrypted_msg_info_text_with_missing_key.txt" + ) + ) intending(hasComponent(ComponentName(getTargetContext(), ImportPrivateKeyActivity::class.java))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) onView(withId(R.id.buttonImportPrivateKey)) - .check(matches(isDisplayed())) - .perform(scrollTo(), click()) + .check(matches(isDisplayed())) + .perform(scrollTo(), click()) PrivateKeysManager.saveKeyFromAssetsToDatabase( - accountEntity = addAccountToDatabaseRule.account, - keyPath = TestConstants.DEFAULT_SECOND_KEY_PRV_STRONG, - passphrase = TestConstants.DEFAULT_STRONG_PASSWORD, - sourceType = KeyImportDetails.SourceType.EMAIL + accountEntity = addAccountToDatabaseRule.account, + keyPath = TestConstants.DEFAULT_SECOND_KEY_PRV_STRONG, + passphrase = TestConstants.DEFAULT_STRONG_PASSWORD, + sourceType = KeyImportDetails.SourceType.EMAIL ) val incomingMsgInfoFixed = - TestGeneralUtil.getObjectFromJson("messages/info/encrypted_msg_info_text_with_missing_key_fixed.json", - IncomingMessageInfo::class.java) + TestGeneralUtil.getObjectFromJson( + "messages/info/encrypted_msg_info_text_with_missing_key_fixed.json", + IncomingMessageInfo::class.java + ) onWebView(withId(R.id.emailWebView)).forceJavascriptEnabled() onWebView(withId(R.id.emailWebView)) - .withElement(findElement(Locator.XPATH, "/html/body")) - .check(webMatches(getText(), equalTo(incomingMsgInfoFixed?.text))) + .withElement(findElement(Locator.XPATH, "/html/body")) + .check(webMatches(getText(), equalTo(incomingMsgInfoFixed?.text))) - PrivateKeysManager.deleteKey(addAccountToDatabaseRule.account, TestConstants.DEFAULT_SECOND_KEY_PRV_STRONG) + PrivateKeysManager.deleteKey( + addAccountToDatabaseRule.account, + TestConstants.DEFAULT_SECOND_KEY_PRV_STRONG + ) } @Test fun testMissingPubKey() { - testMissingKey(getMsgInfo("messages/info/encrypted_msg_info_text_error_one_pub_key.json", - "messages/mime/encrypted_msg_info_plain_text_error_one_pub_key.txt")) + testMissingKey( + getMsgInfo( + "messages/info/encrypted_msg_info_text_error_one_pub_key.json", + "messages/mime/encrypted_msg_info_plain_text_error_one_pub_key.txt" + ) + ) } @Test fun testBadlyFormattedMsg() { - val msgInfo = getMsgInfo("messages/info/encrypted_msg_info_text_error_badly_formatted.json", - "messages/mime/encrypted_msg_info_plain_text_error_badly_formatted.txt") - ?: throw NullPointerException() + val msgInfo = getMsgInfo( + "messages/info/encrypted_msg_info_text_error_badly_formatted.json", + "messages/mime/encrypted_msg_info_plain_text_error_badly_formatted.txt" + ) + ?: throw NullPointerException() assertThat(msgInfo, notNullValue()) @@ -238,11 +280,13 @@ class MessageDetailsActivityTest : BaseTest() { val block = msgInfo.msgBlocks?.get(1) as DecryptErrorMsgBlock val decryptError = block.error - val formatErrorMsg = (getResString(R.string.decrypt_error_message_badly_formatted, - getResString(R.string.app_name)) + "\n\n" + decryptError?.details?.type + ": " + decryptError?.details?.message) + val formatErrorMsg = (getResString( + R.string.decrypt_error_message_badly_formatted, + getResString(R.string.app_name) + ) + "\n\n" + decryptError?.details?.type + ": " + decryptError?.details?.message) onView(withId(R.id.textViewErrorMessage)) - .check(matches(withText(formatErrorMsg))) + .check(matches(withText(formatErrorMsg))) testSwitch(block.content ?: "") matchReplyButtons(details) @@ -250,168 +294,239 @@ class MessageDetailsActivityTest : BaseTest() { @Test fun testMissingKeyErrorChooseSinglePubKey() { - val msgInfo = getMsgInfo("messages/info/encrypted_msg_info_text_with_missing_key.json", - "messages/mime/encrypted_msg_info_text_with_missing_key.txt") + val msgInfo = getMsgInfo( + "messages/info/encrypted_msg_info_text_with_missing_key.json", + "messages/mime/encrypted_msg_info_text_with_missing_key.txt" + ) testMissingKey(msgInfo) onView(withId(R.id.buttonSendOwnPublicKey)) - .check(matches(isDisplayed())) - .perform(scrollTo(), click()) + .check(matches(isDisplayed())) + .perform(scrollTo(), click()) onView(withId(R.id.textViewMessage)).check( - matches(withText(getQuantityString(R.plurals - .tell_sender_to_update_their_settings, 1)))) + matches( + withText( + getQuantityString( + R.plurals + .tell_sender_to_update_their_settings, 1 + ) + ) + ) + ) onView(withId(R.id.buttonOk)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) intended(hasComponent(CreateMessageActivity::class.java.name)) } @Test fun testMissingKeyErrorChooseFromFewPubKeys() { - val msgInfo = getMsgInfo("messages/info/encrypted_msg_info_text_with_missing_key.json", - "messages/mime/encrypted_msg_info_text_with_missing_key.txt") + val msgInfo = getMsgInfo( + "messages/info/encrypted_msg_info_text_with_missing_key.json", + "messages/mime/encrypted_msg_info_text_with_missing_key.txt" + ) testMissingKey(msgInfo) onView(withId(R.id.buttonSendOwnPublicKey)) - .check(matches(isDisplayed())) - .perform(scrollTo(), click()) + .check(matches(isDisplayed())) + .perform(scrollTo(), click()) - PrivateKeysManager.saveKeyFromAssetsToDatabase(addAccountToDatabaseRule + PrivateKeysManager.saveKeyFromAssetsToDatabase( + addAccountToDatabaseRule .account, TestConstants.DEFAULT_SECOND_KEY_PRV_STRONG, - TestConstants.DEFAULT_STRONG_PASSWORD, KeyImportDetails.SourceType.EMAIL) + TestConstants.DEFAULT_STRONG_PASSWORD, KeyImportDetails.SourceType.EMAIL + ) - val msg = getQuantityString(R.plurals - .tell_sender_to_update_their_settings, 2) + val msg = getQuantityString( + R.plurals + .tell_sender_to_update_their_settings, 2 + ) onView(withId(R.id.textViewMessage)) - .check(matches(withText(msg))) + .check(matches(withText(msg))) onData(anything()) - .inAdapterView(withId(R.id.listViewKeys)) - .atPosition(1) - .perform(click()) + .inAdapterView(withId(R.id.listViewKeys)) + .atPosition(1) + .perform(click()) onView(withId(R.id.buttonOk)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) intended(hasComponent(CreateMessageActivity::class.java.name)) } @Test fun testEncryptedMsgTextWithOneAttachment() { - val msgInfo = getMsgInfo("messages/info/encrypted_msg_info_text_with_one_att.json", - "messages/mime/encrypted_msg_info_plain_text_with_one_att.txt", encryptedAttInfo) + val msgInfo = getMsgInfo( + "messages/info/encrypted_msg_info_text_with_one_att.json", + "messages/mime/encrypted_msg_info_plain_text_with_one_att.txt", encryptedAttInfo + ) baseCheckWithAtt(msgInfo, encryptedAttInfo) } @Test fun testEncryptedMsgPlaintextWithPubKey() { - val msgInfo = getMsgInfo("messages/info/encrypted_msg_info_text_with_pub_key.json", - "messages/mime/encrypted_msg_info_text_with_pub_key.txt", pubKeyAttInfo) + val msgInfo = getMsgInfo( + "messages/info/encrypted_msg_info_text_with_pub_key.json", + "messages/mime/encrypted_msg_info_text_with_pub_key.txt", pubKeyAttInfo + ) baseCheckWithAtt(msgInfo, pubKeyAttInfo) - val nodeKeyDetails = PrivateKeysManager.getNodeKeyDetailsFromAssets("pgp/denbond7@flowcrypt.test_pub.asc") + val nodeKeyDetails = + PrivateKeysManager.getNodeKeyDetailsFromAssets("pgp/denbond7@flowcrypt.test_pub.asc") val pgpContact = nodeKeyDetails.primaryPgpContact - onView(withId(R.id.textViewKeyOwnerTemplate)).check(matches(withText( - getResString(R.string.template_message_part_public_key_owner, pgpContact.email)))) + onView(withId(R.id.textViewKeyOwnerTemplate)).check( + matches( + withText( + getResString(R.string.template_message_part_public_key_owner, pgpContact.email) + ) + ) + ) - onView(withId(R.id.textViewFingerprintTemplate)).check(matches(withText( - getHtmlString(getResString(R.string.template_message_part_public_key_fingerprint, - GeneralUtil.doSectionsInText(" ", nodeKeyDetails.fingerprint, 4)!!))))) + onView(withId(R.id.textViewFingerprintTemplate)).check( + matches( + withText( + getHtmlString( + getResString( + R.string.template_message_part_public_key_fingerprint, + GeneralUtil.doSectionsInText(" ", nodeKeyDetails.fingerprint, 4)!! + ) + ) + ) + ) + ) val block = msgInfo?.msgBlocks?.get(1) as PublicKeyMsgBlock onView(withId(R.id.textViewPgpPublicKey)) - .check(matches(not(isDisplayed()))) + .check(matches(not(isDisplayed()))) onView(withId(R.id.switchShowPublicKey)) - .check(matches(not(isChecked()))) - .perform(scrollTo(), click()) + .check(matches(not(isChecked()))) + .perform(scrollTo(), click()) onView(withId(R.id.textViewPgpPublicKey)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(R.id.textViewPgpPublicKey)) - .check(matches(withText(TestGeneralUtil.replaceVersionInKey(block.content)))) + .check(matches(withText(TestGeneralUtil.replaceVersionInKey(block.content)))) onView(withId(R.id.switchShowPublicKey)) - .check(matches(isChecked())) - .perform(scrollTo(), click()) + .check(matches(isChecked())) + .perform(scrollTo(), click()) onView(withId(R.id.textViewPgpPublicKey)) - .check(matches(not(isDisplayed()))) + .check(matches(not(isDisplayed()))) onView(withId(R.id.buttonKeyAction)) - .check(matches(isDisplayed())) - .perform(scrollTo(), click()) + .check(matches(isDisplayed())) + .perform(scrollTo(), click()) onView(withId(R.id.buttonKeyAction)) - .check(matches(not(isDisplayed()))) + .check(matches(not(isDisplayed()))) } @Test fun test8bitEncodingUtf8() { - baseCheck(getMsgInfo("messages/info/msg_info_8bit-utf8.json", - "messages/mime/8bit-utf8.txt")) + baseCheck( + getMsgInfo( + "messages/info/msg_info_8bit-utf8.json", + "messages/mime/8bit-utf8.txt" + ) + ) } @Test fun testToLabelForTwoRecipients() { - baseCheck(getMsgInfo("messages/info/standard_msg_info_plaintext_to_2_recipients.json", - "messages/mime/standard_msg_info_plaintext_to_2_recipients.txt")) + baseCheck( + getMsgInfo( + "messages/info/standard_msg_info_plaintext_to_2_recipients.json", + "messages/mime/standard_msg_info_plaintext_to_2_recipients.txt" + ) + ) val subText = getResString(R.string.me) + ", User" onView(withId(R.id.tVTo)) - .check(matches(withText(getResString(R.string.to_receiver, subText)))) + .check(matches(withText(getResString(R.string.to_receiver, subText)))) } @Test fun testMsgDetailsSingleToReplyToCC() { - val msgInfo = getMsgInfo("messages/info/standard_msg_info_plaintext_single_to_replyto_cc.json", - "messages/mime/standard_msg_info_plaintext_single_to_replyto_to_cc.txt") + val msgInfo = getMsgInfo( + "messages/info/standard_msg_info_plaintext_single_to_replyto_cc.json", + "messages/mime/standard_msg_info_plaintext_single_to_replyto_to_cc.txt" + ) baseCheck(msgInfo) onView(withId(R.id.rVMsgDetails)) - .check(matches(not(isDisplayed()))) + .check(matches(not(isDisplayed()))) onView(withId(R.id.iBShowDetails)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) onView(withId(R.id.rVMsgDetails)) - .check(matches(isDisplayed())) - .check(matches(CustomMatchers.withRecyclerViewItemCount(5))) + .check(matches(isDisplayed())) + .check(matches(CustomMatchers.withRecyclerViewItemCount(5))) onView(withId(R.id.rVMsgDetails)) - .perform(scrollToHolder( - withHeaderInfo(MsgDetailsRecyclerViewAdapter.Header( - name = getResString(R.string.from), - value = "Denis Bondarenko " - )))) + .perform( + scrollToHolder( + withHeaderInfo( + MsgDetailsRecyclerViewAdapter.Header( + name = getResString(R.string.from), + value = "Denis Bondarenko " + ) + ) + ) + ) onView(withId(R.id.rVMsgDetails)) - .perform(scrollToHolder(withHeaderInfo( + .perform( + scrollToHolder( + withHeaderInfo( MsgDetailsRecyclerViewAdapter.Header( - name = getResString(R.string.reply_to), - value = "Denis Bondarenko " - )))) + name = getResString(R.string.reply_to), + value = "Denis Bondarenko " + ) + ) + ) + ) onView(withId(R.id.rVMsgDetails)) - .perform(scrollToHolder(withHeaderInfo( + .perform( + scrollToHolder( + withHeaderInfo( MsgDetailsRecyclerViewAdapter.Header( - name = getResString(R.string.to), - value = "default@flowcrypt.test" - )))) + name = getResString(R.string.to), + value = "default@flowcrypt.test" + ) + ) + ) + ) onView(withId(R.id.rVMsgDetails)) - .perform(scrollToHolder(withHeaderInfo( + .perform( + scrollToHolder( + withHeaderInfo( MsgDetailsRecyclerViewAdapter.Header( - name = getResString(R.string.cc), - value = "ccuser@test" - )))) + name = getResString(R.string.cc), + value = "ccuser@test" + ) + ) + ) + ) val flags = DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_SHOW_TIME or DateUtils.FORMAT_SHOW_YEAR - val datetime = DateUtils.formatDateTime(getTargetContext(), - msgInfo?.msgEntity?.receivedDate ?: 0, flags) + val datetime = DateUtils.formatDateTime( + getTargetContext(), + msgInfo?.msgEntity?.receivedDate ?: 0, flags + ) onView(withId(R.id.rVMsgDetails)) - .perform(scrollToHolder(withHeaderInfo( + .perform( + scrollToHolder( + withHeaderInfo( MsgDetailsRecyclerViewAdapter.Header( - name = getResString(R.string.date), - value = datetime - )))) + name = getResString(R.string.date), + value = datetime + ) + ) + ) + ) } private fun testMissingKey(incomingMsgInfo: IncomingMessageInfo?) { @@ -426,7 +541,7 @@ class MessageDetailsActivityTest : BaseTest() { val errorMsg = getResString(R.string.decrypt_error_current_key_cannot_open_message) onView(withId(R.id.textViewErrorMessage)) - .check(matches(withText(errorMsg))) + .check(matches(withText(errorMsg))) testSwitch(block.content ?: "") matchReplyButtons(details) @@ -434,19 +549,19 @@ class MessageDetailsActivityTest : BaseTest() { private fun testSwitch(content: String) { onView(withId(R.id.textViewOrigPgpMsg)) - .check(matches(not(isDisplayed()))) + .check(matches(not(isDisplayed()))) onView(withId(R.id.switchShowOrigMsg)) - .check(matches(not(isChecked()))) - .perform(scrollTo(), click()) + .check(matches(not(isChecked()))) + .perform(scrollTo(), click()) onView(withId(R.id.textViewOrigPgpMsg)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(R.id.textViewOrigPgpMsg)) - .check(matches(withText(content))) + .check(matches(withText(content))) onView(withId(R.id.switchShowOrigMsg)) - .check(matches(isChecked())) - .perform(scrollTo(), click()) + .check(matches(isChecked())) + .perform(scrollTo(), click()) onView(withId(R.id.textViewOrigPgpMsg)) - .check(matches(not(isDisplayed()))) + .check(matches(not(isDisplayed()))) } private fun baseCheck(incomingMsgInfo: IncomingMessageInfo?) { @@ -458,8 +573,8 @@ class MessageDetailsActivityTest : BaseTest() { onWebView(withId(R.id.emailWebView)).forceJavascriptEnabled() onWebView(withId(R.id.emailWebView)) - .withElement(findElement(Locator.XPATH, "/html/body")) - .check(webMatches(getText(), equalTo(incomingMsgInfo.text))) + .withElement(findElement(Locator.XPATH, "/html/body")) + .check(webMatches(getText(), equalTo(incomingMsgInfo.text))) matchReplyButtons(details) } @@ -472,10 +587,10 @@ class MessageDetailsActivityTest : BaseTest() { onWebView(withId(R.id.emailWebView)).forceJavascriptEnabled() onWebView(withId(R.id.emailWebView)) - .withElement(findElement(Locator.XPATH, "/html/body")) - .check(webMatches(getText(), equalTo(incomingMsgInfo.text))) + .withElement(findElement(Locator.XPATH, "/html/body")) + .check(webMatches(getText(), equalTo(incomingMsgInfo.text))) onView(withId(R.id.layoutAtt)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) matchAtt(att) matchReplyButtons(msgEntity) } @@ -485,64 +600,79 @@ class MessageDetailsActivityTest : BaseTest() { requireNotNull(msgEntity) onView(withId(R.id.textViewSenderAddress)) - .check(matches(withText(EmailUtil.getFirstAddressString(msgEntity.from)))) + .check(matches(withText(EmailUtil.getFirstAddressString(msgEntity.from)))) onView(withId(R.id.textViewDate)) - .check(matches(withText(DateTimeUtil.formatSameDayTime(getTargetContext(), msgEntity.receivedDate)))) + .check( + matches( + withText( + DateTimeUtil.formatSameDayTime( + getTargetContext(), + msgEntity.receivedDate + ) + ) + ) + ) onView(withId(R.id.textViewSubject)) - .check(matches(anyOf(withText(msgEntity.subject), withText(incomingMsgInfo.inlineSubject)))) + .check(matches(anyOf(withText(msgEntity.subject), withText(incomingMsgInfo.inlineSubject)))) } private fun matchAtt(att: AttachmentInfo?) { requireNotNull(att) onView(withId(R.id.textViewAttachmentName)) - .check(matches(withText(att.name))) + .check(matches(withText(att.name))) onView(withId(R.id.textViewAttSize)) - .check(matches(withText(Formatter.formatFileSize(getContext(), att.encodedSize)))) + .check(matches(withText(Formatter.formatFileSize(getContext(), att.encodedSize)))) } private fun matchReplyButtons(msgEntity: MessageEntity) { onView(withId(R.id.imageButtonReplyAll)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(R.id.layoutReplyButton)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(R.id.layoutReplyAllButton)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(R.id.layoutFwdButton)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) if (msgEntity.isEncrypted == true) { onView(withId(R.id.textViewReply)) - .check(matches(withText(getResString(R.string.reply_encrypted)))) + .check(matches(withText(getResString(R.string.reply_encrypted)))) onView(withId(R.id.textViewReplyAll)) - .check(matches(withText(getResString(R.string.reply_all_encrypted)))) + .check(matches(withText(getResString(R.string.reply_all_encrypted)))) onView(withId(R.id.textViewFwd)) - .check(matches(withText(getResString(R.string.forward_encrypted)))) + .check(matches(withText(getResString(R.string.forward_encrypted)))) onView(withId(R.id.imageViewReply)) - .check(matches(withDrawable(R.mipmap.ic_reply_green))) + .check(matches(withDrawable(R.mipmap.ic_reply_green))) onView(withId(R.id.imageViewReplyAll)) - .check(matches(withDrawable(R.mipmap.ic_reply_all_green))) + .check(matches(withDrawable(R.mipmap.ic_reply_all_green))) onView(withId(R.id.imageViewFwd)) - .check(matches(withDrawable(R.mipmap.ic_forward_green))) + .check(matches(withDrawable(R.mipmap.ic_forward_green))) } else { onView(withId(R.id.textViewReply)) - .check(matches(withText(getResString(R.string.reply)))) + .check(matches(withText(getResString(R.string.reply)))) onView(withId(R.id.textViewReplyAll)) - .check(matches(withText(getResString(R.string.reply_all)))) + .check(matches(withText(getResString(R.string.reply_all)))) onView(withId(R.id.textViewFwd)) - .check(matches(withText(getResString(R.string.forward)))) + .check(matches(withText(getResString(R.string.forward)))) onView(withId(R.id.imageViewReply)) - .check(matches(withDrawable(R.mipmap.ic_reply_red))) + .check(matches(withDrawable(R.mipmap.ic_reply_red))) onView(withId(R.id.imageViewReplyAll)) - .check(matches(withDrawable(R.mipmap.ic_reply_all_red))) + .check(matches(withDrawable(R.mipmap.ic_reply_all_red))) onView(withId(R.id.imageViewFwd)) - .check(matches(withDrawable(R.mipmap.ic_forward_red))) + .check(matches(withDrawable(R.mipmap.ic_forward_red))) } } private fun launchActivity(msgEntity: MessageEntity) { - activeActivityRule.launch(MessageDetailsActivity.getIntent(getTargetContext(), localFolder, msgEntity)) + activeActivityRule.launch( + MessageDetailsActivity.getIntent( + getTargetContext(), + localFolder, + msgEntity + ) + ) registerAllIdlingResources() activityScenario?.onActivity { activity -> @@ -556,24 +686,25 @@ class MessageDetailsActivityTest : BaseTest() { testStandardMsgPlaintext() onView(withId(R.id.imageButtonMoreOptions)) - .check(matches(isDisplayed())) - .perform(scrollTo(), click()) + .check(matches(isDisplayed())) + .perform(scrollTo(), click()) onView(withText(title)) - .inRoot(RootMatchers.isPlatformPopup()) - .perform(click()) + .inRoot(RootMatchers.isPlatformPopup()) + .perform(click()) intended(hasComponent(CreateMessageActivity::class.java.name)) onView(withId(R.id.toolbar)) - .check(matches(CustomMatchers.withToolBarText(title))) + .check(matches(CustomMatchers.withToolBarText(title))) } private fun withHeaderInfo(header: MsgDetailsRecyclerViewAdapter.Header): Matcher { return object : BoundedMatcher( - MsgDetailsRecyclerViewAdapter.ViewHolder::class.java) { + MsgDetailsRecyclerViewAdapter.ViewHolder::class.java + ) { override fun matchesSafely(holder: MsgDetailsRecyclerViewAdapter.ViewHolder): Boolean { return holder.tVHeaderName.text.toString() == header.name && holder.tVHeaderValue.text.toString() == header.value diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivityTest.kt index d4442917f6..5f8e0bdf91 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivityTest.kt @@ -43,83 +43,127 @@ import org.junit.runner.RunWith @MediumTest @RunWith(AndroidJUnit4::class) class PreviewImportPgpContactActivityTest : BaseTest() { - override val activeActivityRule = lazyActivityScenarioRule(launchActivity = false) + override val activeActivityRule = + lazyActivityScenarioRule(launchActivity = false) override val activityScenario: ActivityScenario<*>? get() = activeActivityRule.scenario @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(AddAccountToDatabaseRule()) - .around(RetryRule.DEFAULT) - .around(activeActivityRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(AddAccountToDatabaseRule()) + .around(RetryRule.DEFAULT) + .around(activeActivityRule) + .around(ScreenshotTestRule()) - private val singlePublicKeyForUnsavedContact: String? = PrivateKeysManager.getNodeKeyDetailsFromAssets( - "pgp/default@flowcrypt.test_fisrtKey_pub.asc").publicKey + private val singlePublicKeyForUnsavedContact: String? = + PrivateKeysManager.getNodeKeyDetailsFromAssets( + "pgp/default@flowcrypt.test_fisrtKey_pub.asc" + ).publicKey private val tenPubKeys: String = - TestGeneralUtil.readFileFromAssetsAsString("pgp/keys/10_pub_keys_armored_own_header.asc") + TestGeneralUtil.readFileFromAssetsAsString("pgp/keys/10_pub_keys_armored_own_header.asc") @Test fun testShowHelpScreen() { - activeActivityRule.launch(PreviewImportPgpContactActivity.newIntent(getTargetContext(), singlePublicKeyForUnsavedContact)) + activeActivityRule.launch( + PreviewImportPgpContactActivity.newIntent( + getTargetContext(), + singlePublicKeyForUnsavedContact + ) + ) registerAllIdlingResources() testHelpScreen() } @Test fun testIsDisplayedSingleItem() { - val pgpContact = PgpContact("default@flowcrypt.test", null, - singlePublicKeyForUnsavedContact, true, null, null, 0) - FlowCryptRoomDatabase.getDatabase(getTargetContext()).contactsDao().insert(pgpContact.toContactEntity()) - activeActivityRule.launch(PreviewImportPgpContactActivity.newIntent(getTargetContext(), - singlePublicKeyForUnsavedContact)) + val pgpContact = PgpContact( + "default@flowcrypt.test", null, + singlePublicKeyForUnsavedContact, true, null, null, 0 + ) + FlowCryptRoomDatabase.getDatabase(getTargetContext()).contactsDao() + .insert(pgpContact.toContactEntity()) + activeActivityRule.launch( + PreviewImportPgpContactActivity.newIntent( + getTargetContext(), + singlePublicKeyForUnsavedContact + ) + ) registerAllIdlingResources() onView(withId(R.id.recyclerViewContacts)) - .check(RecyclerViewItemCountAssertion(1)) - onView(withText(getResString(R.string.template_message_part_public_key_owner, "default@flowcrypt.test"))) - .check(matches(isDisplayed())) + .check(RecyclerViewItemCountAssertion(1)) + onView( + withText( + getResString( + R.string.template_message_part_public_key_owner, + "default@flowcrypt.test" + ) + ) + ) + .check(matches(isDisplayed())) } @Test fun testIsDisplayedLabelAlreadyImported() { activeActivityRule.launch( - PreviewImportPgpContactActivity.newIntent(getTargetContext(), singlePublicKeyForUnsavedContact)) + PreviewImportPgpContactActivity.newIntent( + getTargetContext(), + singlePublicKeyForUnsavedContact + ) + ) registerAllIdlingResources() onView(withId(R.id.recyclerViewContacts)) - .check(RecyclerViewItemCountAssertion(1)) + .check(RecyclerViewItemCountAssertion(1)) } @Test fun testSaveButtonForSingleContact() { activeActivityRule.launch( - PreviewImportPgpContactActivity.newIntent(getTargetContext(), singlePublicKeyForUnsavedContact)) + PreviewImportPgpContactActivity.newIntent( + getTargetContext(), + singlePublicKeyForUnsavedContact + ) + ) registerAllIdlingResources() onView(withId(R.id.recyclerViewContacts)) - .check(RecyclerViewItemCountAssertion(1)) + .check(RecyclerViewItemCountAssertion(1)) onView(withId(R.id.recyclerViewContacts)) - .perform(RecyclerViewActions.actionOnItemAtPosition(0, - ClickOnViewInRecyclerViewItem(R.id.buttonSaveContact))) + .perform( + RecyclerViewActions.actionOnItemAtPosition( + 0, + ClickOnViewInRecyclerViewItem(R.id.buttonSaveContact) + ) + ) isToastDisplayed(decorView, getResString(R.string.contact_successfully_saved)) } @Test fun testIsImportAllButtonDisplayed() { - activeActivityRule.launch(PreviewImportPgpContactActivity.newIntent(getTargetContext(), tenPubKeys)) + activeActivityRule.launch( + PreviewImportPgpContactActivity.newIntent( + getTargetContext(), + tenPubKeys + ) + ) registerAllIdlingResources() onView(withId(R.id.buttonImportAll)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test fun testLoadLotOfContacts() { val countOfKeys = 10 - activeActivityRule.launch(PreviewImportPgpContactActivity.newIntent(getTargetContext(), tenPubKeys)) + activeActivityRule.launch( + PreviewImportPgpContactActivity.newIntent( + getTargetContext(), + tenPubKeys + ) + ) registerAllIdlingResources() onView(withId(R.id.recyclerViewContacts)) - .check(RecyclerViewItemCountAssertion(countOfKeys)) - .perform(RecyclerViewActions.scrollToPosition(countOfKeys - 1)) + .check(RecyclerViewItemCountAssertion(countOfKeys)) + .perform(RecyclerViewActions.scrollToPosition(countOfKeys - 1)) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PublicKeyDetailsFragmentTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PublicKeyDetailsFragmentTest.kt index 96eca34e5c..1d76bcde3d 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PublicKeyDetailsFragmentTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PublicKeyDetailsFragmentTest.kt @@ -55,7 +55,7 @@ import org.junit.rules.RuleChain import org.junit.rules.TestRule import org.junit.runner.RunWith import java.io.File -import java.util.* +import java.util.Date /** * @author Denis Bondarenko @@ -69,17 +69,26 @@ class PublicKeyDetailsFragmentTest : BaseTest() { override val useIntents: Boolean = true override val activityScenarioRule = activityScenarioRule() - private val keyDetails = PrivateKeysManager.getNodeKeyDetailsFromAssets("pgp/expired@flowcrypt.test_pub.asc") + private val keyDetails = + PrivateKeysManager.getNodeKeyDetailsFromAssets("pgp/expired@flowcrypt.test_pub.asc") @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(AddAccountToDatabaseRule()) - .around(AddContactsToDatabaseRule(listOf(PgpContact(EMAIL_DENBOND7, USER_DENBOND7, - keyDetails.publicKey, true, null, null, 0)))) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(AddAccountToDatabaseRule()) + .around( + AddContactsToDatabaseRule( + listOf( + PgpContact( + EMAIL_DENBOND7, USER_DENBOND7, + keyDetails.publicKey, true, null, null, 0 + ) + ) + ) + ) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Before fun waitData() { @@ -94,20 +103,38 @@ class PublicKeyDetailsFragmentTest : BaseTest() { keyDetails.users.forEachIndexed { index, s -> onView(withText(getResString(R.string.template_user, index + 1, s))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } keyDetails.ids.forEachIndexed { index, s -> onView(withText(getResString(R.string.template_fingerprint_2, index + 1, s.fingerprint))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } onView(withId(R.id.textViewAlgorithm)) - .check(matches(withText(getResString(R.string.template_algorithm, keyDetails.algo.algorithm!!)))) + .check( + matches( + withText( + getResString( + R.string.template_algorithm, + keyDetails.algo.algorithm!! + ) + ) + ) + ) onView(withId(R.id.textViewCreated)) - .check(matches(withText(getResString(R.string.template_created, - DateFormat.getMediumDateFormat(getTargetContext()).format( - Date(keyDetails.created)))))) + .check( + matches( + withText( + getResString( + R.string.template_created, + DateFormat.getMediumDateFormat(getTargetContext()).format( + Date(keyDetails.created) + ) + ) + ) + ) + ) } @Test @@ -115,8 +142,8 @@ class PublicKeyDetailsFragmentTest : BaseTest() { chooseContact() onView(withId(R.id.menuActionCopy)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) isToastDisplayed(decorView, getResString(R.string.public_key_copied_to_clipboard)) UiThreadStatement.runOnUiThread { checkClipboardText(TestGeneralUtil.replaceVersionInKey(keyDetails.publicKey)) @@ -131,23 +158,28 @@ class PublicKeyDetailsFragmentTest : BaseTest() { val fileName = "0x" + keyDetails.fingerprint + "-" + sanitizedEmail + "-publickey" + ".asc" val file = - File(getTargetContext().getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), fileName) + File(getTargetContext().getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), fileName) if (file.exists()) { file.delete() } val resultData = Intent() - resultData.data = FileProvider.getUriForFile(getTargetContext(), Constants.FILE_PROVIDER_AUTHORITY, file) + resultData.data = + FileProvider.getUriForFile(getTargetContext(), Constants.FILE_PROVIDER_AUTHORITY, file) - Intents.intending(AllOf.allOf(IntentMatchers.hasAction(Intent.ACTION_CREATE_DOCUMENT), + Intents.intending( + AllOf.allOf( + IntentMatchers.hasAction(Intent.ACTION_CREATE_DOCUMENT), IntentMatchers.hasCategories(CoreMatchers.hasItem(Matchers.equalTo(Intent.CATEGORY_OPENABLE))), - IntentMatchers.hasType(Constants.MIME_TYPE_PGP_KEY))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)) + IntentMatchers.hasType(Constants.MIME_TYPE_PGP_KEY) + ) + ) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)) onView(withId(R.id.menuActionSave)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) isToastDisplayed(decorView, getResString(R.string.saved)) } @@ -158,11 +190,11 @@ class PublicKeyDetailsFragmentTest : BaseTest() { openActionBarOverflowOrOptionsMenu(getTargetContext()) onView(withText(R.string.delete)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(R.string.no_results)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test @@ -172,7 +204,7 @@ class PublicKeyDetailsFragmentTest : BaseTest() { private fun chooseContact() { onView(withId(R.id.recyclerViewContacts)) - .perform(RecyclerViewActions.actionOnItemAtPosition(0, click())) + .perform(RecyclerViewActions.actionOnItemAtPosition(0, click())) } /** @@ -199,7 +231,8 @@ class PublicKeyDetailsFragmentTest : BaseTest() { @AfterClass @JvmStatic fun removeContactFromDatabase() { - val dao = FlowCryptRoomDatabase.getDatabase(ApplicationProvider.getApplicationContext()).contactsDao() + val dao = + FlowCryptRoomDatabase.getDatabase(ApplicationProvider.getApplicationContext()).contactsDao() dao.getContactByEmail(EMAIL_DENBOND7)?.let { dao.delete(it) } } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SearchBackupsInEmailActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SearchBackupsInEmailActivityTest.kt index bd148c1559..4237372335 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SearchBackupsInEmailActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SearchBackupsInEmailActivityTest.kt @@ -45,12 +45,12 @@ class SearchBackupsInEmailActivityTest : BaseTest() { @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(AddAccountToDatabaseRule()) - .around(AddPrivateKeyToDatabaseRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(AddAccountToDatabaseRule()) + .around(AddPrivateKeyToDatabaseRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test @NotReadyForCI @@ -62,9 +62,9 @@ class SearchBackupsInEmailActivityTest : BaseTest() { @NotReadyForCI fun testIsBackupFound() { onView(withId(R.id.buttonSeeMoreBackupOptions)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(R.id.textViewBackupFound)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test @@ -72,9 +72,9 @@ class SearchBackupsInEmailActivityTest : BaseTest() { fun testShowBackupOptions() { testIsBackupFound() onView(withId(R.id.buttonSeeMoreBackupOptions)) - .perform(click()) + .perform(click()) onView(withId(R.id.buttonBackupAction)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test @@ -82,14 +82,14 @@ class SearchBackupsInEmailActivityTest : BaseTest() { fun testSelectEmailForSavingBackup() { testShowBackupOptions() onView(withId(R.id.radioButtonEmail)) - .check(matches(isDisplayed())) - .perform(click()).check(matches(isChecked())) + .check(matches(isDisplayed())) + .perform(click()).check(matches(isChecked())) onView(withId(R.id.textViewOptionsHint)) - .check(matches(isDisplayed())).check(matches(withText(R.string.backup_as_email_hint))) + .check(matches(isDisplayed())).check(matches(withText(R.string.backup_as_email_hint))) onView(withId(R.id.buttonBackupAction)) - .check(matches(withText(R.string.backup_as_email))) + .check(matches(withText(R.string.backup_as_email))) onView(withId(R.id.radioButtonDownload)) - .check(matches(isDisplayed())).check(matches(not(isChecked()))) + .check(matches(isDisplayed())).check(matches(not(isChecked()))) } @Test @@ -97,13 +97,13 @@ class SearchBackupsInEmailActivityTest : BaseTest() { fun testSelectDownloadToFileForSavingBackup() { testShowBackupOptions() onView(withId(R.id.radioButtonDownload)) - .check(matches(isDisplayed())) - .perform(click()).check(matches(isChecked())) + .check(matches(isDisplayed())) + .perform(click()).check(matches(isChecked())) onView(withId(R.id.textViewOptionsHint)) - .check(matches(isDisplayed())).check(matches(withText(R.string.backup_as_download_hint))) + .check(matches(isDisplayed())).check(matches(withText(R.string.backup_as_download_hint))) onView(withId(R.id.buttonBackupAction)) - .check(matches(withText(R.string.backup_as_a_file))) + .check(matches(withText(R.string.backup_as_a_file))) onView(withId(R.id.radioButtonEmail)) - .check(matches(isDisplayed())).check(matches(not(isChecked()))) + .check(matches(isDisplayed())).check(matches(not(isChecked()))) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SearchMessagesActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SearchMessagesActivityTest.kt index 76405ba901..ad6ee97339 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SearchMessagesActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SearchMessagesActivityTest.kt @@ -54,21 +54,27 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class SearchMessagesActivityTest : BaseEmailListActivityTest() { - private val accountRule = AddAccountToDatabaseRule(AccountDaoManager.getDefaultAccountDao().copy(areContactsLoaded = true)) + private val accountRule = AddAccountToDatabaseRule( + AccountDaoManager.getDefaultAccountDao().copy(areContactsLoaded = true) + ) override val activityScenarioRule = activityScenarioRule( - intent = SearchMessagesActivity.newIntent(getTargetContext(), DEFAULT_QUERY_TEXT, LocalFolder( - account = accountRule.account.email, - fullName = FOLDER_NAME, - folderAlias = FOLDER_NAME))) + intent = SearchMessagesActivity.newIntent( + getTargetContext(), DEFAULT_QUERY_TEXT, LocalFolder( + account = accountRule.account.email, + fullName = FOLDER_NAME, + folderAlias = FOLDER_NAME + ) + ) + ) @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(accountRule) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(accountRule) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Before fun waitData() { @@ -80,38 +86,38 @@ class SearchMessagesActivityTest : BaseEmailListActivityTest() { @NotReadyForCI fun testDefaultSearchQueryAtStart() { onView(allOf(withId(R.id.menuSearch), withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(isAssignableFrom(EditText::class.java)) - .check(matches(withText(DEFAULT_QUERY_TEXT))) + .check(matches(withText(DEFAULT_QUERY_TEXT))) onView(withId(R.id.rVMsgs)) - .check(matches(not(withEmptyRecyclerView()))) + .check(matches(not(withEmptyRecyclerView()))) } @Test @NotReadyForCI fun testSearchQuery() { onView(withId(R.id.rVMsgs)) - .check(matches(withRecyclerViewItemCount(1))).check(matches(isDisplayed())) + .check(matches(withRecyclerViewItemCount(1))).check(matches(isDisplayed())) onView(allOf(withId(R.id.menuSearch), withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(isAssignableFrom(EditText::class.java)) - .check(matches(withText(DEFAULT_QUERY_TEXT))) - .perform(clearText(), typeText(SECOND_QUERY_TEXT), pressImeActionButton()) + .check(matches(withText(DEFAULT_QUERY_TEXT))) + .perform(clearText(), typeText(SECOND_QUERY_TEXT), pressImeActionButton()) //todo-denbond7 Need to improve this code Thread.sleep(2000) onView(withId(R.id.rVMsgs)) - .check(matches(withRecyclerViewItemCount(2))).check(matches(isDisplayed())) + .check(matches(withRecyclerViewItemCount(2))).check(matches(isDisplayed())) } @Test @NotReadyForCI fun testSearchOverSubjectBodyFrom() { onView(allOf(withId(R.id.menuSearch), withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(isAssignableFrom(EditText::class.java)) - .check(matches(withText(DEFAULT_QUERY_TEXT))) - .perform(clearText(), typeText(QUERY_TEXT_FOR_SUBJECT_BODY_FROM), pressImeActionButton()) + .check(matches(withText(DEFAULT_QUERY_TEXT))) + .perform(clearText(), typeText(QUERY_TEXT_FOR_SUBJECT_BODY_FROM), pressImeActionButton()) //todo-denbond7 Need to improve this code Thread.sleep(2000) onView(withId(R.id.rVMsgs)) @@ -122,9 +128,9 @@ class SearchMessagesActivityTest : BaseEmailListActivityTest() { @NotReadyForCI fun testShowNotEmptyList() { onView(withId(R.id.rVMsgs)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(R.id.rVMsgs)) - .check(matches(not(withEmptyRecyclerView()))) + .check(matches(not(withEmptyRecyclerView()))) } @Test @@ -138,30 +144,31 @@ class SearchMessagesActivityTest : BaseEmailListActivityTest() { @NotReadyForCI fun testCheckNoResults() { onView(allOf(withId(R.id.menuSearch), withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(isAssignableFrom(EditText::class.java)) - .perform( - clearText(), - typeText("The string with no results"), - pressImeActionButton()) + .perform( + clearText(), + typeText("The string with no results"), + pressImeActionButton() + ) //todo-denbond7 Need to improve this code Thread.sleep(2000) onView(withId(R.id.tVEmpty)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test @NotReadyForCI fun testClearSearchView() { onView(allOf(withId(R.id.menuSearch), withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(androidx.appcompat.R.id.search_close_btn)) - .perform(click()) + .perform(click()) onView(isAssignableFrom(EditText::class.java)) - .check(matches(withText(isEmptyString()))) - .check(matches(withHint(InstrumentationRegistry.getInstrumentation().targetContext.getString(R.string.search)))) + .check(matches(withText(isEmptyString()))) + .check(matches(withHint(InstrumentationRegistry.getInstrumentation().targetContext.getString(R.string.search)))) } companion object { diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SelectContactsActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SelectContactsActivityTest.kt index b620f89424..5e04309b0b 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SelectContactsActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SelectContactsActivityTest.kt @@ -59,12 +59,12 @@ class SelectContactsActivityTest : BaseTest() { @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(AddAccountToDatabaseRule()) - .around(AddContactsToDatabaseRule(CONTACTS)) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(AddAccountToDatabaseRule()) + .around(AddContactsToDatabaseRule(CONTACTS)) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Before open fun registerFilterIdling() { @@ -95,21 +95,28 @@ class SelectContactsActivityTest : BaseTest() { Thread.sleep(1000) onView(withId(R.id.emptyView)) - .check(matches(isDisplayed())).check(matches(withText(R.string.no_results))) + .check(matches(isDisplayed())).check(matches(withText(R.string.no_results))) } @Test fun testShowListContacts() { onView(withId(R.id.emptyView)) - .check(matches(not(isDisplayed()))) + .check(matches(not(isDisplayed()))) for (i in EMAILS.indices) { if (i % 2 == 0) { - onView(withId(R.id.recyclerViewContacts)).perform(actionOnItem - (hasDescendant(allOf(withId(R.id.textViewName), withText(getUserName(EMAILS[i])))), doNothing())) + onView(withId(R.id.recyclerViewContacts)).perform( + actionOnItem + ( + hasDescendant(allOf(withId(R.id.textViewName), withText(getUserName(EMAILS[i])))), + doNothing() + ) + ) } else { - onView(withId(R.id.recyclerViewContacts)).perform(actionOnItem - (hasDescendant(allOf(withId(R.id.textViewOnlyEmail), withText(EMAILS[i]))), doNothing())) + onView(withId(R.id.recyclerViewContacts)).perform( + actionOnItem + (hasDescendant(allOf(withId(R.id.textViewOnlyEmail), withText(EMAILS[i]))), doNothing()) + ) } } } @@ -117,8 +124,8 @@ class SelectContactsActivityTest : BaseTest() { @Test fun testCheckSearchExistingContact() { onView(withId(R.id.menuSearch)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) for (i in EMAILS.indices) { if (i % 2 == 0) { @@ -132,13 +139,13 @@ class SelectContactsActivityTest : BaseTest() { @Test fun testNoResults() { onView(withId(R.id.menuSearch)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(com.google.android.material.R.id.search_src_text)) - .perform(clearText(), typeText("some email")) + .perform(clearText(), typeText("some email")) closeSoftKeyboard() onView(withId(R.id.emptyView)) - .check(matches(isDisplayed())).check(matches(withText(R.string.no_results))) + .check(matches(isDisplayed())).check(matches(withText(R.string.no_results))) } private fun clearContactsFromDatabase() { @@ -151,18 +158,19 @@ class SelectContactsActivityTest : BaseTest() { private fun checkIsTypedUserFound(viewId: Int, viewText: String) { onView(withId(com.google.android.material.R.id.search_src_text)) - .perform(clearText(), typeText(viewText)) + .perform(clearText(), typeText(viewText)) closeSoftKeyboard() onView(withId(viewId)) - .check(matches(isDisplayed())).check(matches(withText(viewText))) + .check(matches(isDisplayed())).check(matches(withText(viewText))) } companion object { private val EMAILS = arrayOf( - "contact_0@flowcrypt.test", - "contact_1@flowcrypt.test", - "contact_2@flowcrypt.test", - "contact_3@flowcrypt.test") + "contact_0@flowcrypt.test", + "contact_1@flowcrypt.test", + "contact_2@flowcrypt.test", + "contact_3@flowcrypt.test" + ) private val CONTACTS = ArrayList() init { diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SettingsActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SettingsActivityTest.kt index b7eee22dcb..050668ce45 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SettingsActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SettingsActivityTest.kt @@ -45,11 +45,11 @@ class SettingsActivityTest : BaseTest() { @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(AddAccountToDatabaseRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(AddAccountToDatabaseRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test fun testShowHelpScreen() { @@ -85,7 +85,10 @@ class SettingsActivityTest : BaseTest() { @Test fun testShowLegalScreen() { - checkIsScreenDisplaying(getResString(R.string.experimental), getResString(R.string.experimental_settings)) + checkIsScreenDisplaying( + getResString(R.string.experimental), + getResString(R.string.experimental_settings) + ) } private fun checkIsScreenDisplaying(screenName: String) { @@ -94,9 +97,9 @@ class SettingsActivityTest : BaseTest() { private fun checkIsScreenDisplaying(commandName: String, screenName: String) { onView(withText(commandName)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(allOf(withText(screenName), withParent(withId(R.id.toolbar)))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ShareIntentsTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ShareIntentsTest.kt index 7b7f6d2b27..c14487f29b 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ShareIntentsTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ShareIntentsTest.kt @@ -48,7 +48,9 @@ import java.io.File import java.io.UnsupportedEncodingException import java.net.URLDecoder import java.nio.charset.StandardCharsets -import java.util.* +import java.util.ArrayList +import java.util.Random +import java.util.UUID /** * @author Denis Bondarenko @@ -59,17 +61,18 @@ import java.util.* @MediumTest @RunWith(AndroidJUnit4::class) class ShareIntentsTest : BaseTest() { - override val activeActivityRule = lazyActivityScenarioRule(launchActivity = false) + override val activeActivityRule = + lazyActivityScenarioRule(launchActivity = false) override val activityScenario: ActivityScenario<*>? get() = activeActivityRule.scenario @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(AddAccountToDatabaseRule()) - .around(RetryRule.DEFAULT) - .around(activeActivityRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(AddAccountToDatabaseRule()) + .around(RetryRule.DEFAULT) + .around(activeActivityRule) + .around(ScreenshotTestRule()) private val randomActionForRFC6068: String get() = if (Random().nextBoolean()) Intent.ACTION_SENDTO else Intent.ACTION_VIEW @@ -83,48 +86,72 @@ class ShareIntentsTest : BaseTest() { @Test fun testToSubjectBody() { - activeActivityRule.launch(genIntentForUri(randomActionForRFC6068, "mailto:" + recipients[0] - + "?subject=" + ENCODED_SUBJECT + "&body=" + ENCODED_BODY)) + activeActivityRule.launch( + genIntentForUri( + randomActionForRFC6068, "mailto:" + recipients[0] + + "?subject=" + ENCODED_SUBJECT + "&body=" + ENCODED_BODY + ) + ) registerAllIdlingResources() checkViewsOnScreen(1, ENCODED_SUBJECT, ENCODED_BODY, 0) } @Test fun testToParamSubjectBody() { - activeActivityRule.launch(genIntentForUri(randomActionForRFC6068, "mailto:?to=" + recipients[0] - + "&subject=" + ENCODED_SUBJECT + "&body=" + ENCODED_BODY)) + activeActivityRule.launch( + genIntentForUri( + randomActionForRFC6068, "mailto:?to=" + recipients[0] + + "&subject=" + ENCODED_SUBJECT + "&body=" + ENCODED_BODY + ) + ) registerAllIdlingResources() checkViewsOnScreen(1, ENCODED_SUBJECT, ENCODED_BODY, 0) } @Test fun testToToParamSubjectBody() { - activeActivityRule.launch(genIntentForUri(randomActionForRFC6068, "mailto:" + recipients[0] - + "?to=" + recipients[1] + "&subject=" + ENCODED_SUBJECT + "&body=" + ENCODED_BODY)) + activeActivityRule.launch( + genIntentForUri( + randomActionForRFC6068, "mailto:" + recipients[0] + + "?to=" + recipients[1] + "&subject=" + ENCODED_SUBJECT + "&body=" + ENCODED_BODY + ) + ) registerAllIdlingResources() checkViewsOnScreen(2, ENCODED_SUBJECT, ENCODED_BODY, 0) } @Test fun testToParamToSubjectBody() { - activeActivityRule.launch(genIntentForUri(randomActionForRFC6068, "mailto:?to=" + recipients[0] - + "," + recipients[1] + "&subject=" + ENCODED_SUBJECT + "&body=" + ENCODED_BODY)) + activeActivityRule.launch( + genIntentForUri( + randomActionForRFC6068, "mailto:?to=" + recipients[0] + + "," + recipients[1] + "&subject=" + ENCODED_SUBJECT + "&body=" + ENCODED_BODY + ) + ) registerAllIdlingResources() checkViewsOnScreen(2, ENCODED_SUBJECT, ENCODED_BODY, 0) } @Test fun testMultiToSubjectBody() { - activeActivityRule.launch(genIntentForUri(randomActionForRFC6068, "mailto:" + recipients[0] - + "," + recipients[1] + "?subject=" + ENCODED_SUBJECT + "&body=" + ENCODED_BODY)) + activeActivityRule.launch( + genIntentForUri( + randomActionForRFC6068, "mailto:" + recipients[0] + + "," + recipients[1] + "?subject=" + ENCODED_SUBJECT + "&body=" + ENCODED_BODY + ) + ) registerAllIdlingResources() checkViewsOnScreen(2, ENCODED_SUBJECT, ENCODED_BODY, 0) } @Test fun testMultiToParamSubjectBody() { - activeActivityRule.launch(genIntentForUri(randomActionForRFC6068, "mailto:?to=" + recipients[0] - + "&to=" + recipients[1] + "&subject=" + ENCODED_SUBJECT + "&body=" + ENCODED_BODY)) + activeActivityRule.launch( + genIntentForUri( + randomActionForRFC6068, "mailto:?to=" + recipients[0] + + "&to=" + recipients[1] + "&subject=" + ENCODED_SUBJECT + "&body=" + ENCODED_BODY + ) + ) registerAllIdlingResources() checkViewsOnScreen(2, ENCODED_SUBJECT, ENCODED_BODY, 0) } @@ -145,14 +172,28 @@ class ShareIntentsTest : BaseTest() { @Test fun testSendExtSubject() { - activeActivityRule.launch(generateIntentWithExtras(Intent.ACTION_SEND, Intent.EXTRA_SUBJECT, null, 0)) + activeActivityRule.launch( + generateIntentWithExtras( + Intent.ACTION_SEND, + Intent.EXTRA_SUBJECT, + null, + 0 + ) + ) registerAllIdlingResources() checkViewsOnScreen(0, Intent.EXTRA_SUBJECT, null, 0) } @Test fun testSendExtBody() { - activeActivityRule.launch(generateIntentWithExtras(Intent.ACTION_SEND, null, Intent.EXTRA_TEXT, 0)) + activeActivityRule.launch( + generateIntentWithExtras( + Intent.ACTION_SEND, + null, + Intent.EXTRA_TEXT, + 0 + ) + ) registerAllIdlingResources() checkViewsOnScreen(0, null, Intent.EXTRA_TEXT, 0) } @@ -166,45 +207,78 @@ class ShareIntentsTest : BaseTest() { @Test fun testSendExtSubjectExtBody() { - activeActivityRule.launch(generateIntentWithExtras(Intent.ACTION_SEND, Intent.EXTRA_SUBJECT, - Intent.EXTRA_TEXT, 0)) + activeActivityRule.launch( + generateIntentWithExtras( + Intent.ACTION_SEND, Intent.EXTRA_SUBJECT, + Intent.EXTRA_TEXT, 0 + ) + ) registerAllIdlingResources() checkViewsOnScreen(0, Intent.EXTRA_SUBJECT, Intent.EXTRA_TEXT, 0) } @Test fun testSendExtSubjectAtt() { - activeActivityRule.launch(generateIntentWithExtras(Intent.ACTION_SEND, Intent.EXTRA_SUBJECT, null, 1)) + activeActivityRule.launch( + generateIntentWithExtras( + Intent.ACTION_SEND, + Intent.EXTRA_SUBJECT, + null, + 1 + ) + ) registerAllIdlingResources() checkViewsOnScreen(0, Intent.EXTRA_SUBJECT, null, 1) } @Test fun testSendExtBodyAtt() { - activeActivityRule.launch(generateIntentWithExtras(Intent.ACTION_SEND, null, Intent.EXTRA_TEXT, 1)) + activeActivityRule.launch( + generateIntentWithExtras( + Intent.ACTION_SEND, + null, + Intent.EXTRA_TEXT, + 1 + ) + ) registerAllIdlingResources() checkViewsOnScreen(0, null, Intent.EXTRA_TEXT, 1) } @Test fun testSendExtSubjectExtBodyAtt() { - activeActivityRule.launch(generateIntentWithExtras(Intent.ACTION_SEND, Intent.EXTRA_SUBJECT, - Intent.EXTRA_TEXT, 1)) + activeActivityRule.launch( + generateIntentWithExtras( + Intent.ACTION_SEND, Intent.EXTRA_SUBJECT, + Intent.EXTRA_TEXT, 1 + ) + ) registerAllIdlingResources() checkViewsOnScreen(0, Intent.EXTRA_SUBJECT, Intent.EXTRA_TEXT, 1) } @Test fun testSendMultipleMultiAtt() { - activeActivityRule.launch(generateIntentWithExtras(Intent.ACTION_SEND_MULTIPLE, null, null, atts.size)) + activeActivityRule.launch( + generateIntentWithExtras( + Intent.ACTION_SEND_MULTIPLE, + null, + null, + atts.size + ) + ) registerAllIdlingResources() checkViewsOnScreen(0, null, null, atts.size) } @Test fun testSendMultipleExtSubjectExtBodyMultiAtt() { - activeActivityRule.launch(generateIntentWithExtras(Intent.ACTION_SEND_MULTIPLE, Intent.EXTRA_SUBJECT, - Intent.EXTRA_TEXT, atts.size)) + activeActivityRule.launch( + generateIntentWithExtras( + Intent.ACTION_SEND_MULTIPLE, Intent.EXTRA_SUBJECT, + Intent.EXTRA_TEXT, atts.size + ) + ) registerAllIdlingResources() checkViewsOnScreen(0, Intent.EXTRA_SUBJECT, Intent.EXTRA_TEXT, atts.size) } @@ -212,9 +286,14 @@ class ShareIntentsTest : BaseTest() { @Test fun testDoNotSupportAttWithFileSchema() { activeActivityRule.launch( - generateIntentWithExtras(Intent.ACTION_SEND, Intent.EXTRA_SUBJECT, Intent.EXTRA_TEXT, 0).apply { - putExtra(Intent.EXTRA_STREAM, atts.first()) - }) + generateIntentWithExtras( + Intent.ACTION_SEND, + Intent.EXTRA_SUBJECT, + Intent.EXTRA_TEXT, + 0 + ).apply { + putExtra(Intent.EXTRA_STREAM, atts.first()) + }) registerAllIdlingResources() checkViewsOnScreen(0, Intent.EXTRA_SUBJECT, Intent.EXTRA_TEXT, 0) } @@ -229,8 +308,10 @@ class ShareIntentsTest : BaseTest() { } - private fun generateIntentWithExtras(action: String?, extraSubject: String?, extraMsg: CharSequence?, - attachmentsCount: Int): Intent { + private fun generateIntentWithExtras( + action: String?, extraSubject: String?, extraMsg: CharSequence?, + attachmentsCount: Int + ): Intent { val intent = Intent(getTargetContext(), CreateMessageActivity::class.java) intent.action = action intent.putExtra(Intent.EXTRA_SUBJECT, extraSubject) @@ -250,11 +331,16 @@ class ShareIntentsTest : BaseTest() { return intent } - private fun checkViewsOnScreen(recipientsCount: Int, subject: String?, body: CharSequence?, attachmentsCount: Int) { + private fun checkViewsOnScreen( + recipientsCount: Int, + subject: String?, + body: CharSequence?, + attachmentsCount: Int + ) { onView(withText(R.string.compose)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(R.id.editTextFrom)) - .check(matches(isDisplayed())).check(matches(withText(not(isEmptyString())))) + .check(matches(isDisplayed())).check(matches(withText(not(isEmptyString())))) closeSoftKeyboard() checkRecipients(recipientsCount) @@ -265,17 +351,17 @@ class ShareIntentsTest : BaseTest() { private fun checkAtts(attachmentsCount: Int) { onView(withId(R.id.layoutAtts)) - .check(matches(hasChildCount(attachmentsCount))) + .check(matches(hasChildCount(attachmentsCount))) when { attachmentsCount > 0 -> { if (attachmentsCount == 1) { onView(withText(atts.first().name)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } else { for (att in atts) { onView(withText(att.name)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } } } @@ -285,20 +371,22 @@ class ShareIntentsTest : BaseTest() { private fun checkBody(body: CharSequence?) { if (body != null) { onView(withId(R.id.editTextEmailMessage)) - .check(matches(isDisplayed())).check(matches(withText(getRidOfCharacterSubstitutes(body.toString())))) + .check(matches(isDisplayed())) + .check(matches(withText(getRidOfCharacterSubstitutes(body.toString())))) } else { onView(withId(R.id.editTextEmailMessage)) - .check(matches(isDisplayed())).check(matches(withText(isEmptyString()))) + .check(matches(isDisplayed())).check(matches(withText(isEmptyString()))) } } private fun checkSubject(subject: String?) { if (subject != null) { onView(withId(R.id.editTextEmailSubject)) - .check(matches(isDisplayed())).check(matches(withText(getRidOfCharacterSubstitutes(subject)))) + .check(matches(isDisplayed())) + .check(matches(withText(getRidOfCharacterSubstitutes(subject)))) } else { onView(withId(R.id.editTextEmailSubject)) - .check(matches(isDisplayed())).check(matches(withText(isEmptyString()))) + .check(matches(isDisplayed())).check(matches(withText(isEmptyString()))) } } @@ -306,11 +394,11 @@ class ShareIntentsTest : BaseTest() { if (recipientsCount > 0) { for (i in 0 until recipientsCount) { onView(withId(R.id.editTextRecipientTo)) - .check(matches(isDisplayed())).check(matches(withText(containsString(recipients[i])))) + .check(matches(isDisplayed())).check(matches(withText(containsString(recipients[i])))) } } else { onView(withId(R.id.editTextRecipientTo)) - .check(matches(isDisplayed())).check(matches(withText(isEmptyString()))) + .check(matches(isDisplayed())).check(matches(withText(isEmptyString()))) } } @@ -324,8 +412,10 @@ class ShareIntentsTest : BaseTest() { } private fun genUriFromFile(file: File): Uri { - return FileProvider.getUriForFile(ApplicationProvider.getApplicationContext(), Constants - .FILE_PROVIDER_AUTHORITY, file) + return FileProvider.getUriForFile( + ApplicationProvider.getApplicationContext(), Constants + .FILE_PROVIDER_AUTHORITY, file + ) } companion object { @@ -335,8 +425,9 @@ class ShareIntentsTest : BaseTest() { private lateinit var atts: MutableList private val recipients: Array = arrayOf( - TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER, - TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER) + TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER, + TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER + ) @BeforeClass @JvmStatic @@ -352,31 +443,39 @@ class ShareIntentsTest : BaseTest() { @get:ClassRule @JvmStatic - val mockWebServerRule = FlowCryptMockWebServerRule(TestConstants.MOCK_WEB_SERVER_PORT, object : Dispatcher() { - override fun dispatch(request: RecordedRequest): MockResponse { - if (request.path?.startsWith("/pub", ignoreCase = true) == true) { - val lastSegment = request.requestUrl?.pathSegments?.lastOrNull() - - when { - TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER.equals(lastSegment, true) -> { - return MockResponse().setResponseCode(404).setBody(TestGeneralUtil.readResourcesAsString("2.txt")) - } - - TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER.equals(lastSegment, true) -> { - return MockResponse().setResponseCode(200).setBody(TestGeneralUtil.readResourcesAsString("3.txt")) + val mockWebServerRule = + FlowCryptMockWebServerRule(TestConstants.MOCK_WEB_SERVER_PORT, object : Dispatcher() { + override fun dispatch(request: RecordedRequest): MockResponse { + if (request.path?.startsWith("/pub", ignoreCase = true) == true) { + val lastSegment = request.requestUrl?.pathSegments?.lastOrNull() + + when { + TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER.equals(lastSegment, true) -> { + return MockResponse().setResponseCode(404) + .setBody(TestGeneralUtil.readResourcesAsString("2.txt")) + } + + TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER.equals(lastSegment, true) -> { + return MockResponse().setResponseCode(200) + .setBody(TestGeneralUtil.readResourcesAsString("3.txt")) + } } } - } - return MockResponse().setResponseCode(404) - } - }) + return MockResponse().setResponseCode(404) + } + }) private fun createFilesForAtts() { atts = mutableListOf() for (i in 0 until ATTACHMENTS_COUNT) { - atts.add(TestGeneralUtil.createFileAndFillWithContent("$i.txt", UUID.randomUUID().toString())) + atts.add( + TestGeneralUtil.createFileAndFillWithContent( + "$i.txt", + UUID.randomUUID().toString() + ) + ) } } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SignInActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SignInActivityTest.kt index 32a31a1c44..6243b1e4f5 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SignInActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SignInActivityTest.kt @@ -45,25 +45,25 @@ class SignInActivityTest : BaseTest() { @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test fun testUseOtherEmailProviders() { onView(withId(R.id.buttonOtherEmailProvider)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(R.string.or_use_your_credentials_to_connect)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test fun testUseGmail() { onView(withId(R.id.buttonSignInWithGmail)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) //check that the Google Sign-in screen displayed intended(toPackage("com.google.android.gms")) } @@ -71,9 +71,9 @@ class SignInActivityTest : BaseTest() { @Test fun testShowSecurityScreen() { onView(withId(R.id.buttonSecurity)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(allOf(withText(R.string.security), withParent(withId(R.id.toolbar)))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/StandardReplyWithServiceInfoAndOneFileTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/StandardReplyWithServiceInfoAndOneFileTest.kt index 8d539d4f62..393c8e9b6c 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/StandardReplyWithServiceInfoAndOneFileTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/StandardReplyWithServiceInfoAndOneFileTest.kt @@ -56,49 +56,67 @@ import org.junit.runner.RunWith @MediumTest @RunWith(AndroidJUnit4::class) class StandardReplyWithServiceInfoAndOneFileTest : BaseTest() { - private val addAccountToDatabaseRule: AddAccountToDatabaseRule = AddAccountToDatabaseRule(AccountDaoManager.getDefaultAccountDao().copy(areContactsLoaded = true)) - private val attachmentInfo = AttachmentInfo(name = "test.txt", - email = addAccountToDatabaseRule.account.email, - encodedSize = STRING.length.toLong(), - rawData = STRING, - type = JavaEmailConstants.MIME_TYPE_TEXT_PLAIN, - folder = "SENT", - id = EmailUtil.generateContentId(), - isProtected = true) - - private val incomingMsgInfo = TestGeneralUtil.getObjectFromJson("messages/info/encrypted_msg_info_text.json", IncomingMessageInfo::class.java)!! - private val serviceInfo = ServiceInfo(isToFieldEditable = false, - isFromFieldEditable = false, - isMsgEditable = false, - isSubjectEditable = false, - isMsgTypeSwitchable = false, - hasAbilityToAddNewAtt = false, - systemMsg = getResString(R.string.message_was_encrypted_for_wrong_key), - atts = listOf(attachmentInfo)) + private val addAccountToDatabaseRule: AddAccountToDatabaseRule = AddAccountToDatabaseRule( + AccountDaoManager.getDefaultAccountDao().copy(areContactsLoaded = true) + ) + private val attachmentInfo = AttachmentInfo( + name = "test.txt", + email = addAccountToDatabaseRule.account.email, + encodedSize = STRING.length.toLong(), + rawData = STRING, + type = JavaEmailConstants.MIME_TYPE_TEXT_PLAIN, + folder = "SENT", + id = EmailUtil.generateContentId(), + isProtected = true + ) + + private val incomingMsgInfo = TestGeneralUtil.getObjectFromJson( + "messages/info/encrypted_msg_info_text.json", + IncomingMessageInfo::class.java + )!! + private val serviceInfo = ServiceInfo( + isToFieldEditable = false, + isFromFieldEditable = false, + isMsgEditable = false, + isSubjectEditable = false, + isMsgTypeSwitchable = false, + hasAbilityToAddNewAtt = false, + systemMsg = getResString(R.string.message_was_encrypted_for_wrong_key), + atts = listOf(attachmentInfo) + ) override val useIntents: Boolean = true override val activityScenarioRule = activityScenarioRule( - intent = Intent(getTargetContext(), CreateMessageActivity::class.java).apply { - putExtra(CreateMessageActivity.EXTRA_KEY_INCOMING_MESSAGE_INFO, incomingMsgInfo) - putExtra(CreateMessageActivity.EXTRA_KEY_MESSAGE_TYPE, MessageType.REPLY as Parcelable) - putExtra(CreateMessageActivity.EXTRA_KEY_MESSAGE_ENCRYPTION_TYPE, MessageEncryptionType.STANDARD as Parcelable) - putExtra(CreateMessageActivity.EXTRA_KEY_SERVICE_INFO, serviceInfo) - }) + intent = Intent(getTargetContext(), CreateMessageActivity::class.java).apply { + putExtra(CreateMessageActivity.EXTRA_KEY_INCOMING_MESSAGE_INFO, incomingMsgInfo) + putExtra(CreateMessageActivity.EXTRA_KEY_MESSAGE_TYPE, MessageType.REPLY as Parcelable) + putExtra( + CreateMessageActivity.EXTRA_KEY_MESSAGE_ENCRYPTION_TYPE, + MessageEncryptionType.STANDARD as Parcelable + ) + putExtra(CreateMessageActivity.EXTRA_KEY_SERVICE_INFO, serviceInfo) + }) @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(addAccountToDatabaseRule) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(addAccountToDatabaseRule) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test fun testFrom() { onView(withId(R.id.editTextFrom)) - .perform(scrollTo()) - .check(matches(allOf(isDisplayed(), - if (serviceInfo.isFromFieldEditable) isFocusable() else not(isFocusable())))) + .perform(scrollTo()) + .check( + matches( + allOf( + isDisplayed(), + if (serviceInfo.isFromFieldEditable) isFocusable() else not(isFocusable()) + ) + ) + ) } @Test @@ -112,31 +130,49 @@ class StandardReplyWithServiceInfoAndOneFileTest : BaseTest() { + autoCorrectSeparator) onView(withId(R.id.editTextRecipientTo)) - .perform(scrollTo()) - .check(matches(allOf(isDisplayed(), withText(textWithSeparator), - if (serviceInfo.isToFieldEditable) isFocusable() else not(isFocusable())))) + .perform(scrollTo()) + .check( + matches( + allOf( + isDisplayed(), withText(textWithSeparator), + if (serviceInfo.isToFieldEditable) isFocusable() else not(isFocusable()) + ) + ) + ) } @Test fun testSubject() { onView(withId(R.id.editTextEmailSubject)) - .perform(scrollTo()) - .check(matches(allOf(isDisplayed(), - if (serviceInfo.isSubjectEditable) isFocusable() else not(isFocusable())))) + .perform(scrollTo()) + .check( + matches( + allOf( + isDisplayed(), + if (serviceInfo.isSubjectEditable) isFocusable() else not(isFocusable()) + ) + ) + ) } @Test fun testEmailMsg() { onView(withId(R.id.editTextEmailMessage)) - .perform(scrollTo()) - .check(matches(allOf(isDisplayed(), + .perform(scrollTo()) + .check( + matches( + allOf( + isDisplayed(), if (TextUtils.isEmpty(serviceInfo.systemMsg)) withText(isEmptyString()) else withText(serviceInfo.systemMsg), - if (serviceInfo.isMsgEditable) isFocusable() else not(isFocusable())))) + if (serviceInfo.isMsgEditable) isFocusable() else not(isFocusable()) + ) + ) + ) if (serviceInfo.isMsgEditable) { onView(withId(R.id.editTextEmailMessage)) - .perform(scrollTo(), replaceText(STRING)) + .perform(scrollTo(), replaceText(STRING)) } } @@ -144,7 +180,7 @@ class StandardReplyWithServiceInfoAndOneFileTest : BaseTest() { fun testAvailabilityAddingAtts() { if (!serviceInfo.hasAbilityToAddNewAtt) { onView(withId(R.id.menuActionAttachFile)) - .check(doesNotExist()) + .check(doesNotExist()) } } @@ -152,9 +188,9 @@ class StandardReplyWithServiceInfoAndOneFileTest : BaseTest() { fun testDisabledSwitchingBetweenEncryptionTypes() { if (!serviceInfo.isMsgTypeSwitchable) { onView(withText(R.string.switch_to_standard_email)) - .check(doesNotExist()) + .check(doesNotExist()) onView(withText(R.string.switch_to_secure_email)) - .check(doesNotExist()) + .check(doesNotExist()) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BaseCreateOrImportKeyActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BaseCreateOrImportKeyActivityTest.kt index 9e34abf096..3a5fa3052d 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BaseCreateOrImportKeyActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BaseCreateOrImportKeyActivityTest.kt @@ -38,14 +38,18 @@ abstract class BaseCreateOrImportKeyActivityTest : BaseTest() { @Test fun testClickOnButtonImportMyKey() { - intending(allOf(hasComponent(ComponentName(getTargetContext(), ImportPrivateKeyActivity::class.java)), + intending( + allOf( + hasComponent(ComponentName(getTargetContext(), ImportPrivateKeyActivity::class.java)), hasExtraWithKey(BaseImportKeyActivity.KEY_EXTRA_IS_SYNC_ENABLE), hasExtraWithKey(BaseImportKeyActivity.KEY_EXTRA_TITLE), hasExtraWithKey(BaseImportKeyActivity.KEY_EXTRA_PRIVATE_KEY_IMPORT_MODEL_FROM_CLIPBOARD), - hasExtraWithKey(BaseImportKeyActivity.KEY_EXTRA_IS_THROW_ERROR_IF_DUPLICATE_FOUND))) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) + hasExtraWithKey(BaseImportKeyActivity.KEY_EXTRA_IS_THROW_ERROR_IF_DUPLICATE_FOUND) + ) + ) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, null)) onView(withId(R.id.buttonImportMyKey)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) Assert.assertTrue(activityScenarioRule?.scenario?.result?.resultCode == Activity.RESULT_OK) } @@ -53,8 +57,8 @@ abstract class BaseCreateOrImportKeyActivityTest : BaseTest() { @Test fun testClickOnButtonSelectAnotherAccount() { onView(withId(R.id.buttonSelectAnotherAccount)) - .perform(scrollTo(), click()) + .perform(scrollTo(), click()) Assert.assertTrue(activityScenarioRule?.scenario?.result?.resultCode == CreateOrImportKeyActivity.RESULT_CODE_USE_ANOTHER_ACCOUNT) } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BaseEmailListActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BaseEmailListActivityTest.kt index 66044aa8e9..d25bacd994 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BaseEmailListActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BaseEmailListActivityTest.kt @@ -33,14 +33,19 @@ abstract class BaseEmailListActivityTest : BaseTest() { protected fun testRunMsgDetailsActivity(position: Int) { onView(withId(R.id.rVMsgs)) - .perform(RecyclerViewActions.actionOnItemAtPosition(position, click())) + .perform( + RecyclerViewActions.actionOnItemAtPosition( + position, + click() + ) + ) intended(hasComponent(MessageDetailsActivity::class.java.name)) onView(withId(R.id.textViewSenderAddress)) - .check(matches(isDisplayed())).check(matches(withText(not(isEmptyString())))) + .check(matches(isDisplayed())).check(matches(withText(not(isEmptyString())))) onView(withId(R.id.textViewSubject)) - .check(matches(isDisplayed())).check(matches(withText(not(isEmptyString())))) + .check(matches(isDisplayed())).check(matches(withText(not(isEmptyString())))) onView(withId(R.id.textViewDate)) - .check(matches(isDisplayed())).check(matches(withText(not(isEmptyString())))) + .check(matches(isDisplayed())).check(matches(withText(not(isEmptyString())))) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BasePassphraseActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BasePassphraseActivityTest.kt index f464b84ded..e1d22c4569 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BasePassphraseActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BasePassphraseActivityTest.kt @@ -20,7 +20,7 @@ import com.flowcrypt.email.base.BaseTest import org.hamcrest.Matchers.isEmptyString import org.hamcrest.Matchers.startsWith import org.junit.Test -import java.util.* +import java.util.Locale /** * @author Denis Bondarenko @@ -32,22 +32,22 @@ abstract class BasePassphraseActivityTest : BaseTest() { @Test fun testShowDialogWithPasswordRecommendation() { onView(withId(R.id.imageButtonShowPasswordHint)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(R.id.webView)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(R.id.buttonOk)) - .perform(click()) + .perform(click()) onView(withId(R.id.textViewFirstPasswordCheckTitle)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test fun testEmptyFirstPassPhrase() { closeSoftKeyboard() onView(withId(R.id.buttonSetPassPhrase)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) checkIsNonEmptyHintShown() } @@ -56,7 +56,7 @@ abstract class BasePassphraseActivityTest : BaseTest() { fun testEmptySecondPassPhrase() { testShowRepeatingPassPhraseScreen() onView(withId(R.id.buttonConfirmPassPhrases)) - .perform(click()) + .perform(click()) checkIsNonEmptyHintShown() } @@ -64,12 +64,12 @@ abstract class BasePassphraseActivityTest : BaseTest() { @Test fun testShowRepeatingPassPhraseScreen() { onView(withId(R.id.editTextKeyPassword)) - .perform(scrollTo(), replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) + .perform(scrollTo(), replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) onView(withId(R.id.buttonSetPassPhrase)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(R.id.buttonConfirmPassPhrases)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test @@ -77,14 +77,14 @@ abstract class BasePassphraseActivityTest : BaseTest() { testShowRepeatingPassPhraseScreen() onView(withId(R.id.editTextKeyPasswordSecond)) - .check(matches(isDisplayed())) - .perform(scrollTo(), replaceText("some text"), closeSoftKeyboard()) + .check(matches(isDisplayed())) + .perform(scrollTo(), replaceText("some text"), closeSoftKeyboard()) onView(withId(R.id.buttonConfirmPassPhrases)) - .perform(click()) + .perform(click()) onView(withText(getResString(R.string.pass_phrases_do_not_match))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(com.google.android.material.R.id.snackbar_action)) - .check(matches(isDisplayed())).perform(click()) + .check(matches(isDisplayed())).perform(click()) } @Test @@ -92,10 +92,10 @@ abstract class BasePassphraseActivityTest : BaseTest() { testShowRepeatingPassPhraseScreen() onView(withId(R.id.buttonUseAnotherPassPhrase)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(R.id.imageButtonShowPasswordHint)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } @Test @@ -103,40 +103,44 @@ abstract class BasePassphraseActivityTest : BaseTest() { testShowRepeatingPassPhraseScreen() onView(withId(R.id.editTextKeyPasswordSecond)) - .check(matches(isDisplayed())) - .perform(replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) + .check(matches(isDisplayed())) + .perform(replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) onView(withId(R.id.buttonUseAnotherPassPhrase)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(R.id.buttonSetPassPhrase)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) testShowRepeatingPassPhraseScreen() onView(withId(R.id.editTextKeyPasswordSecond)) - .check(matches(isDisplayed())).check(matches(withText(isEmptyString()))) + .check(matches(isDisplayed())).check(matches(withText(isEmptyString()))) } @Test fun testChangingQualityOfPassPhrase() { - val passPhrases = arrayOf(WEAK_PASSWORD, POOR_PASSWORD, REASONABLE_PASSWORD, GOOD_PASSWORD, - GREAT_PASSWORD, PERFECT_PASSWORD) - - val degreeOfReliabilityOfPassPhrase = arrayOf(getResString(R.string.password_quality_weak), - getResString(R.string.password_quality_poor), - getResString(R.string.password_quality_reasonable), - getResString(R.string.password_quality_good), - getResString(R.string.password_quality_great), - getResString(R.string.password_quality_perfect)) + val passPhrases = arrayOf( + WEAK_PASSWORD, POOR_PASSWORD, REASONABLE_PASSWORD, GOOD_PASSWORD, + GREAT_PASSWORD, PERFECT_PASSWORD + ) + + val degreeOfReliabilityOfPassPhrase = arrayOf( + getResString(R.string.password_quality_weak), + getResString(R.string.password_quality_poor), + getResString(R.string.password_quality_reasonable), + getResString(R.string.password_quality_good), + getResString(R.string.password_quality_great), + getResString(R.string.password_quality_perfect) + ) for (i in passPhrases.indices) { onView(withId(R.id.editTextKeyPassword)) - .check(matches(isDisplayed())) - .perform(replaceText(passPhrases[i])) + .check(matches(isDisplayed())) + .perform(replaceText(passPhrases[i])) onView(withId(R.id.textViewPasswordQualityInfo)) - .check(matches(withText(startsWith(degreeOfReliabilityOfPassPhrase[i].toUpperCase(Locale.getDefault()))))) + .check(matches(withText(startsWith(degreeOfReliabilityOfPassPhrase[i].toUpperCase(Locale.getDefault()))))) onView(withId(R.id.editTextKeyPassword)) - .check(matches(isDisplayed())) - .perform(clearText()) + .check(matches(isDisplayed())) + .perform(clearText()) } } @@ -146,28 +150,28 @@ abstract class BasePassphraseActivityTest : BaseTest() { for (passPhrase in badPassPhrases) { onView(withId(R.id.editTextKeyPassword)) - .check(matches(isDisplayed())) - .perform(replaceText(passPhrase), closeSoftKeyboard()) + .check(matches(isDisplayed())) + .perform(replaceText(passPhrase), closeSoftKeyboard()) onView(withId(R.id.buttonSetPassPhrase)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withText(getResString(R.string.select_stronger_pass_phrase))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(android.R.id.button1)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(R.id.editTextKeyPassword)) - .check(matches(isDisplayed())) - .perform(clearText()) + .check(matches(isDisplayed())) + .perform(clearText()) } } protected fun checkIsNonEmptyHintShown() { onView(withText(getResString(R.string.passphrase_must_be_non_empty))) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) onView(withId(com.google.android.material.R.id.snackbar_action)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) } companion object { diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BaseSignActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BaseSignActivityTest.kt index b8317d31a8..0c0c456b22 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BaseSignActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/base/BaseSignActivityTest.kt @@ -32,15 +32,17 @@ abstract class BaseSignActivityTest : BaseTest() { val intent = Intent() intent.putExtra("googleSignInAccount", GoogleSignInAccount.zaa(signInAccountJson)) - val signInIntent = GoogleSignIn.getClient(getTargetContext(), - GoogleApiClientHelper.generateGoogleSignInOptions()).signInIntent + val signInIntent = GoogleSignIn.getClient( + getTargetContext(), + GoogleApiClientHelper.generateGoogleSignInOptions() + ).signInIntent Intents.intending(IntentMatchers.hasComponent(signInIntent.component)) - .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, intent)) + .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, intent)) Espresso.onView(ViewMatchers.withId(R.id.buttonSignInWithGmail)) - .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) - .perform(ViewActions.click()) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + .perform(ViewActions.click()) } protected fun genMockGoogleSignInAccountJson(email: String): String { @@ -64,4 +66,4 @@ abstract class BaseSignActivityTest : BaseTest() { " ]\n" + "}" } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/AddNewAccountActivityEnterpriseTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/AddNewAccountActivityEnterpriseTest.kt index b2b049e983..a89425f127 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/AddNewAccountActivityEnterpriseTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/AddNewAccountActivityEnterpriseTest.kt @@ -57,11 +57,11 @@ class AddNewAccountActivityEnterpriseTest : BaseSignActivityTest() { @get:Rule val ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(AddAccountToDatabaseRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(AddAccountToDatabaseRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test @NotReadyForCI @@ -70,7 +70,7 @@ class AddNewAccountActivityEnterpriseTest : BaseSignActivityTest() { intended(hasComponent(CreateOrImportKeyActivity::class.java.name)) onView(withId(R.id.buttonCreateNewKey)) - .check(matches(not(isDisplayed()))) + .check(matches(not(isDisplayed()))) } companion object { @@ -78,28 +78,39 @@ class AddNewAccountActivityEnterpriseTest : BaseSignActivityTest() { @get:ClassRule @JvmStatic - val mockWebServerRule = FlowCryptMockWebServerRule(TestConstants.MOCK_WEB_SERVER_PORT, object : Dispatcher() { - override fun dispatch(request: RecordedRequest): MockResponse { - val gson = ApiHelper.getInstance(InstrumentationRegistry.getInstrumentation().targetContext).gson - val model = gson.fromJson(InputStreamReader(request.body.inputStream()), LoginModel::class.java) + val mockWebServerRule = + FlowCryptMockWebServerRule(TestConstants.MOCK_WEB_SERVER_PORT, object : Dispatcher() { + override fun dispatch(request: RecordedRequest): MockResponse { + val gson = + ApiHelper.getInstance(InstrumentationRegistry.getInstrumentation().targetContext).gson + val model = + gson.fromJson(InputStreamReader(request.body.inputStream()), LoginModel::class.java) - if (request.path.equals("/account/login")) { - when (model.account) { - EMAIL_WITH_NO_PRV_CREATE_RULE -> return MockResponse().setResponseCode(200) + if (request.path.equals("/account/login")) { + when (model.account) { + EMAIL_WITH_NO_PRV_CREATE_RULE -> return MockResponse().setResponseCode(200) .setBody(gson.toJson(LoginResponse(null, isVerified = true))) + } } - } - if (request.path.equals("/account/get")) { - when (model.account) { - EMAIL_WITH_NO_PRV_CREATE_RULE -> return MockResponse().setResponseCode(200) - .setBody(gson.toJson(DomainRulesResponse(null, DomainRules(listOf - ("NO_PRV_CREATE", "NO_PRV_BACKUP"))))) + if (request.path.equals("/account/get")) { + when (model.account) { + EMAIL_WITH_NO_PRV_CREATE_RULE -> return MockResponse().setResponseCode(200) + .setBody( + gson.toJson( + DomainRulesResponse( + null, DomainRules( + listOf + ("NO_PRV_CREATE", "NO_PRV_BACKUP") + ) + ) + ) + ) + } } - } - return MockResponse().setResponseCode(404) - } - }) + return MockResponse().setResponseCode(404) + } + }) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/CreateOrImportKeyActivityEnterpriseTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/CreateOrImportKeyActivityEnterpriseTest.kt index 1e5a088a4b..0d4c538da5 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/CreateOrImportKeyActivityEnterpriseTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/CreateOrImportKeyActivityEnterpriseTest.kt @@ -37,22 +37,23 @@ import org.junit.runner.RunWith class CreateOrImportKeyActivityEnterpriseTest : BaseCreateOrImportKeyActivityTest() { override val useIntents: Boolean = true override val activityScenarioRule = activityScenarioRule( - intent = CreateOrImportKeyActivity.newIntent( - context = getTargetContext(), - accountEntity = AccountDaoManager.getAccountDao("enterprise_account_no_prv_create.json"), - isShowAnotherAccountBtnEnabled = true - )) + intent = CreateOrImportKeyActivity.newIntent( + context = getTargetContext(), + accountEntity = AccountDaoManager.getAccountDao("enterprise_account_no_prv_create.json"), + isShowAnotherAccountBtnEnabled = true + ) + ) @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test fun testCreateNewKeyNotExist() { onView(withId(R.id.buttonCreateNewKey)) - .check(matches(not(isDisplayed()))) + .check(matches(not(isDisplayed()))) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/CreatePrivateKeyActivityEnterpriseTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/CreatePrivateKeyActivityEnterpriseTest.kt index fd662c8ac9..89f2594741 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/CreatePrivateKeyActivityEnterpriseTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/CreatePrivateKeyActivityEnterpriseTest.kt @@ -53,64 +53,74 @@ import java.io.InputStreamReader @RunWith(AndroidJUnit4::class) class CreatePrivateKeyActivityEnterpriseTest : BasePassphraseActivityTest() { override val activityScenarioRule = activityScenarioRule( - intent = Intent(getTargetContext(), CreatePrivateKeyActivity::class.java).apply { - putExtra(CreatePrivateKeyActivity.KEY_EXTRA_ACCOUNT, AccountDaoManager - .getAccountDao("enterprise_account_enforce_attester_submit.json") - .copy(email = EMAIL_ENFORCE_ATTESTER_SUBMIT)) - }) + intent = Intent(getTargetContext(), CreatePrivateKeyActivity::class.java).apply { + putExtra( + CreatePrivateKeyActivity.KEY_EXTRA_ACCOUNT, AccountDaoManager + .getAccountDao("enterprise_account_enforce_attester_submit.json") + .copy(email = EMAIL_ENFORCE_ATTESTER_SUBMIT) + ) + }) @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test fun testFailAttesterSubmit() { onView(withId(R.id.editTextKeyPassword)) - .check(matches(isDisplayed())) - .perform(replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) + .check(matches(isDisplayed())) + .perform(replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) onView(withId(R.id.buttonSetPassPhrase)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) onView(withId(R.id.editTextKeyPasswordSecond)) - .check(matches(isDisplayed())) - .perform(replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) + .check(matches(isDisplayed())) + .perform(replaceText(PERFECT_PASSWORD), closeSoftKeyboard()) onView(withId(R.id.buttonConfirmPassPhrases)) - .check(matches(isDisplayed())) - .perform(click()) + .check(matches(isDisplayed())) + .perform(click()) checkIsSnackbarDisplayedAndClick(SUBMIT_API_ERROR_RESPONSE.apiError?.msg!!) checkIsSnackBarDisplayed() onView(withText(SUBMIT_API_ERROR_RESPONSE.apiError?.msg)) - .check(matches(isDisplayed())) + .check(matches(isDisplayed())) } companion object { const val EMAIL_ENFORCE_ATTESTER_SUBMIT = "enforce_attester_submit@example.com" - val SUBMIT_API_ERROR_RESPONSE = InitialLegacySubmitResponse(ApiError(400, "Invalid email " + - "address", "internal_error"), false) + val SUBMIT_API_ERROR_RESPONSE = InitialLegacySubmitResponse( + ApiError( + 400, "Invalid email " + + "address", "internal_error" + ), false + ) @get:ClassRule @JvmStatic - val mockWebServerRule = FlowCryptMockWebServerRule(TestConstants.MOCK_WEB_SERVER_PORT, object : Dispatcher() { - override fun dispatch(request: RecordedRequest): MockResponse { - val gson = ApiHelper.getInstance(InstrumentationRegistry.getInstrumentation().targetContext).gson - val model = gson.fromJson(InputStreamReader(request.body.inputStream()), - InitialLegacySubmitModel::class.java) + val mockWebServerRule = + FlowCryptMockWebServerRule(TestConstants.MOCK_WEB_SERVER_PORT, object : Dispatcher() { + override fun dispatch(request: RecordedRequest): MockResponse { + val gson = + ApiHelper.getInstance(InstrumentationRegistry.getInstrumentation().targetContext).gson + val model = gson.fromJson( + InputStreamReader(request.body.inputStream()), + InitialLegacySubmitModel::class.java + ) - if (request.path.equals("/initial/legacy_submit")) { - when (model.email) { - EMAIL_ENFORCE_ATTESTER_SUBMIT -> return MockResponse().setResponseCode(200) + if (request.path.equals("/initial/legacy_submit")) { + when (model.email) { + EMAIL_ENFORCE_ATTESTER_SUBMIT -> return MockResponse().setResponseCode(200) .setBody(gson.toJson(SUBMIT_API_ERROR_RESPONSE)) + } } - } - return MockResponse().setResponseCode(404) - } - }) + return MockResponse().setResponseCode(404) + } + }) } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/SettingsActivityEnterpriseTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/SettingsActivityEnterpriseTest.kt index 0e11f64457..36742077db 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/SettingsActivityEnterpriseTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/SettingsActivityEnterpriseTest.kt @@ -39,18 +39,21 @@ class SettingsActivityEnterpriseTest : BaseTest() { @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(AddAccountToDatabaseRule( - AccountDaoManager.getAccountDao("enterprise_account_no_prv_backup.json"))) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around( + AddAccountToDatabaseRule( + AccountDaoManager.getAccountDao("enterprise_account_no_prv_backup.json") + ) + ) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test fun testBackupsDisabled() { //need to wait database updates Thread.sleep(1000) onView(withText(getResString(R.string.backups))) - .check(doesNotExist()) + .check(doesNotExist()) } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/SignInActivityEnterpriseTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/SignInActivityEnterpriseTest.kt index 4b381035f3..98e521f051 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/SignInActivityEnterpriseTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/enterprise/SignInActivityEnterpriseTest.kt @@ -63,10 +63,10 @@ class SignInActivityEnterpriseTest : BaseSignActivityTest() { @get:Rule var ruleChain: TestRule = RuleChain - .outerRule(ClearAppSettingsRule()) - .around(RetryRule.DEFAULT) - .around(activityScenarioRule) - .around(ScreenshotTestRule()) + .outerRule(ClearAppSettingsRule()) + .around(RetryRule.DEFAULT) + .around(activityScenarioRule) + .around(ScreenshotTestRule()) @Test fun testErrorLogin() { @@ -93,7 +93,7 @@ class SignInActivityEnterpriseTest : BaseSignActivityTest() { intended(hasComponent(CreateOrImportKeyActivity::class.java.name)) onView(withId(R.id.buttonCreateNewKey)) - .check(matches(not(isDisplayed()))) + .check(matches(not(isDisplayed()))) } companion object { @@ -102,48 +102,67 @@ class SignInActivityEnterpriseTest : BaseSignActivityTest() { const val EMAIL_LOGIN_NOT_VERIFIED = "login_not_verified@example.com" const val EMAIL_DOMAIN_RULES_ERROR = "domain_rules_error@example.com" - val LOGIN_API_ERROR_RESPONSE = LoginResponse(ApiError(400, "Something wrong happened.", - "api input: missing key: token"), null) + val LOGIN_API_ERROR_RESPONSE = LoginResponse( + ApiError( + 400, "Something wrong happened.", + "api input: missing key: token" + ), null + ) - val DOMAIN_RULES_ERROR_RESPONSE = DomainRulesResponse(ApiError(401, - "Not logged in or unknown account", "auth"), null) + val DOMAIN_RULES_ERROR_RESPONSE = DomainRulesResponse( + ApiError( + 401, + "Not logged in or unknown account", "auth" + ), null + ) @get:ClassRule @JvmStatic - val mockWebServerRule = FlowCryptMockWebServerRule(TestConstants.MOCK_WEB_SERVER_PORT, object : Dispatcher() { - override fun dispatch(request: RecordedRequest): MockResponse { - val gson = ApiHelper.getInstance(InstrumentationRegistry.getInstrumentation().targetContext).gson - val model = gson.fromJson(InputStreamReader(request.body.inputStream()), LoginModel::class.java) - - if (request.path.equals("/account/login")) { - when (model.account) { - EMAIL_LOGIN_ERROR -> return MockResponse().setResponseCode(200) + val mockWebServerRule = + FlowCryptMockWebServerRule(TestConstants.MOCK_WEB_SERVER_PORT, object : Dispatcher() { + override fun dispatch(request: RecordedRequest): MockResponse { + val gson = + ApiHelper.getInstance(InstrumentationRegistry.getInstrumentation().targetContext).gson + val model = + gson.fromJson(InputStreamReader(request.body.inputStream()), LoginModel::class.java) + + if (request.path.equals("/account/login")) { + when (model.account) { + EMAIL_LOGIN_ERROR -> return MockResponse().setResponseCode(200) .setBody(gson.toJson(LOGIN_API_ERROR_RESPONSE)) - EMAIL_LOGIN_NOT_VERIFIED -> return MockResponse().setResponseCode(200) + EMAIL_LOGIN_NOT_VERIFIED -> return MockResponse().setResponseCode(200) .setBody(gson.toJson(LoginResponse(null, isVerified = false))) - EMAIL_DOMAIN_RULES_ERROR -> return MockResponse().setResponseCode(200) + EMAIL_DOMAIN_RULES_ERROR -> return MockResponse().setResponseCode(200) .setBody(gson.toJson(LoginResponse(null, isVerified = true))) - EMAIL_WITH_NO_PRV_CREATE_RULE -> return MockResponse().setResponseCode(200) + EMAIL_WITH_NO_PRV_CREATE_RULE -> return MockResponse().setResponseCode(200) .setBody(gson.toJson(LoginResponse(null, isVerified = true))) + } } - } - if (request.path.equals("/account/get")) { - when (model.account) { - EMAIL_DOMAIN_RULES_ERROR -> return MockResponse().setResponseCode(200) + if (request.path.equals("/account/get")) { + when (model.account) { + EMAIL_DOMAIN_RULES_ERROR -> return MockResponse().setResponseCode(200) .setBody(gson.toJson(DOMAIN_RULES_ERROR_RESPONSE)) - EMAIL_WITH_NO_PRV_CREATE_RULE -> return MockResponse().setResponseCode(200) - .setBody(gson.toJson(DomainRulesResponse(null, DomainRules(listOf - ("NO_PRV_CREATE", "NO_PRV_BACKUP"))))) + EMAIL_WITH_NO_PRV_CREATE_RULE -> return MockResponse().setResponseCode(200) + .setBody( + gson.toJson( + DomainRulesResponse( + null, DomainRules( + listOf + ("NO_PRV_CREATE", "NO_PRV_BACKUP") + ) + ) + ) + ) + } } - } - return MockResponse().setResponseCode(404) - } - }) + return MockResponse().setResponseCode(404) + } + }) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/AccountDaoManager.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/AccountDaoManager.kt index ae52b04727..2b659a8efe 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/AccountDaoManager.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/AccountDaoManager.kt @@ -17,7 +17,10 @@ class AccountDaoManager { companion object { @JvmStatic fun getDefaultAccountDao(): AccountEntity { - return TestGeneralUtil.readObjectFromResources("default_account.json", AccountEntity::class.java) + return TestGeneralUtil.readObjectFromResources( + "default_account.json", + AccountEntity::class.java + ) } @JvmStatic @@ -27,8 +30,10 @@ class AccountDaoManager { @JvmStatic fun getUserWithMoreThan21Letters(): AccountEntity { - return TestGeneralUtil.readObjectFromResources("user_with_more_than_21_letters_account.json", - AccountEntity::class.java) + return TestGeneralUtil.readObjectFromResources( + "user_with_more_than_21_letters_account.json", + AccountEntity::class.java + ) } } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/AuthCredentialsManager.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/AuthCredentialsManager.kt index adf2a02211..bde246b539 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/AuthCredentialsManager.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/AuthCredentialsManager.kt @@ -22,8 +22,10 @@ class AuthCredentialsManager { } fun getLocalWithOneBackupAuthCreds(): AuthCredentials { - return TestGeneralUtil.readObjectFromResources("user_with_one_backup.json", AuthCredentials::class.java) + return TestGeneralUtil.readObjectFromResources( + "user_with_one_backup.json", + AuthCredentials::class.java + ) } } } - diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/PrivateKeysManager.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/PrivateKeysManager.kt index 97f0d2848c..3c68ac87b9 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/PrivateKeysManager.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/PrivateKeysManager.kt @@ -14,7 +14,7 @@ import com.flowcrypt.email.security.KeyStoreCryptoManager import com.flowcrypt.email.security.model.PgpKeyDetails import com.flowcrypt.email.security.pgp.PgpKey import org.pgpainless.key.collection.PGPKeyRingCollection -import java.util.* +import java.util.ArrayList /** * This tool can help manage private keys in the database. For testing purposes only. diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/TestGeneralUtil.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/TestGeneralUtil.kt index 668b4d69da..ad721e9ce4 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/TestGeneralUtil.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/TestGeneralUtil.kt @@ -23,7 +23,7 @@ import java.io.IOException import java.io.InputStream import java.io.RandomAccessFile import java.nio.charset.StandardCharsets -import java.util.* +import java.util.UUID /** * @author Denis Bondarenko @@ -35,7 +35,8 @@ class TestGeneralUtil { companion object { @JvmStatic fun readObjectFromResources(path: String, aClass: Class): T { - val json = IOUtils.toString(aClass.classLoader!!.getResourceAsStream(path), StandardCharsets.UTF_8) + val json = + IOUtils.toString(aClass.classLoader!!.getResourceAsStream(path), StandardCharsets.UTF_8) return Gson().fromJson(json, aClass) } @@ -46,7 +47,10 @@ class TestGeneralUtil { @JvmStatic fun readResourcesAsString(path: String): String { - return IOUtils.toString(TestGeneralUtil::class.java.classLoader!!.getResourceAsStream(path), StandardCharsets.UTF_8) + return IOUtils.toString( + TestGeneralUtil::class.java.classLoader!!.getResourceAsStream(path), + StandardCharsets.UTF_8 + ) } @JvmStatic @@ -56,22 +60,25 @@ class TestGeneralUtil { @JvmStatic fun readFileFromAssetsAsString( - filePath: String, - context: Context = InstrumentationRegistry.getInstrumentation().context): String { + filePath: String, + context: Context = InstrumentationRegistry.getInstrumentation().context + ): String { return IOUtils.toString(context.assets.open(filePath), "UTF-8") } @JvmStatic fun readFileFromAssetsAsByteArray( - filePath: String, - context: Context = InstrumentationRegistry.getInstrumentation().context): ByteArray { + filePath: String, + context: Context = InstrumentationRegistry.getInstrumentation().context + ): ByteArray { return context.assets.open(filePath).readBytes() } @JvmStatic fun readFileFromAssetsAsStream( - filePath: String, - context: Context = InstrumentationRegistry.getInstrumentation().context): InputStream { + filePath: String, + context: Context = InstrumentationRegistry.getInstrumentation().context + ): InputStream { return context.assets.open(filePath) } @@ -86,8 +93,10 @@ class TestGeneralUtil { @JvmStatic fun createFileAndFillWithContent(fileName: String, fileText: String): File { - val file = File(InstrumentationRegistry.getInstrumentation().targetContext - .getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), fileName) + val file = File( + InstrumentationRegistry.getInstrumentation().targetContext + .getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), fileName + ) try { FileOutputStream(file).use { outputStream -> outputStream.write(fileText.toByteArray()) } } catch (e: Exception) { @@ -98,8 +107,10 @@ class TestGeneralUtil { } @JvmStatic - fun createFileAndFillWithContent(temporaryFolder: TemporaryFolder, - fileName: String, fileText: String): File { + fun createFileAndFillWithContent( + temporaryFolder: TemporaryFolder, + fileName: String, fileText: String + ): File { val file = temporaryFolder.newFile(fileName) try { FileOutputStream(file).use { outputStream -> outputStream.write(fileText.toByteArray()) } @@ -111,8 +122,10 @@ class TestGeneralUtil { } @JvmStatic - fun createFileWithGivenSize(fileSizeInBytes: Long, temporaryFolder: TemporaryFolder, - fileName: String = UUID.randomUUID().toString()): File { + fun createFileWithGivenSize( + fileSizeInBytes: Long, temporaryFolder: TemporaryFolder, + fileName: String = UUID.randomUUID().toString() + ): File { return temporaryFolder.newFile(fileName).apply { RandomAccessFile(this, "rw").apply { setLength(fileSizeInBytes) @@ -156,9 +169,11 @@ class TestGeneralUtil { return Intent().apply { val context: Context = ApplicationProvider.getApplicationContext() val uri = FileProvider.getUriForFile(context, Constants.FILE_PROVIDER_AUTHORITY, file) - context.grantUriPermission(BuildConfig.APPLICATION_ID, uri, - Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or - Intent.FLAG_GRANT_READ_URI_PERMISSION) + context.grantUriPermission( + BuildConfig.APPLICATION_ID, uri, + Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or + Intent.FLAG_GRANT_READ_URI_PERMISSION + ) data = uri flags = Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/gson/MsgBlockAdapter.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/gson/MsgBlockAdapter.kt index 9e1a4a7b63..71a63e7496 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/gson/MsgBlockAdapter.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/util/gson/MsgBlockAdapter.kt @@ -5,8 +5,8 @@ package com.flowcrypt.email.util.gson -import com.flowcrypt.email.api.retrofit.response.model.node.GenericMsgBlock import com.flowcrypt.email.api.retrofit.response.model.node.DecryptErrorMsgBlock +import com.flowcrypt.email.api.retrofit.response.model.node.GenericMsgBlock import com.flowcrypt.email.api.retrofit.response.model.node.MsgBlock import com.flowcrypt.email.api.retrofit.response.model.node.PublicKeyMsgBlock import com.google.gson.JsonDeserializationContext @@ -21,15 +21,26 @@ import java.lang.reflect.Type * E-mail: DenBond7@gmail.com */ class MsgBlockAdapter : JsonDeserializer { - override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): MsgBlock? { + override fun deserialize( + json: JsonElement, + typeOfT: Type, + context: JsonDeserializationContext + ): MsgBlock? { val jsonObject = json.asJsonObject - val type = context.deserialize(jsonObject.get("type"), MsgBlock.Type::class.java) ?: return null + val type = context.deserialize(jsonObject.get("type"), MsgBlock.Type::class.java) + ?: return null when (type) { - MsgBlock.Type.PUBLIC_KEY -> return context.deserialize(json, PublicKeyMsgBlock::class.java) + MsgBlock.Type.PUBLIC_KEY -> return context.deserialize( + json, + PublicKeyMsgBlock::class.java + ) - MsgBlock.Type.DECRYPT_ERROR -> return context.deserialize(json, DecryptErrorMsgBlock::class.java) + MsgBlock.Type.DECRYPT_ERROR -> return context.deserialize( + json, + DecryptErrorMsgBlock::class.java + ) else -> return context.deserialize(json, GenericMsgBlock::class.java) } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/viewaction/CustomActions.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/viewaction/CustomActions.kt index 5a16af4561..34711deaef 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/viewaction/CustomActions.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/viewaction/CustomActions.kt @@ -19,4 +19,4 @@ class CustomActions { return EmptyAction() } } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/viewaction/NavigateToItemViewAction.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/viewaction/NavigateToItemViewAction.kt index 71657d682a..d0ce63430f 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/viewaction/NavigateToItemViewAction.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/viewaction/NavigateToItemViewAction.kt @@ -57,10 +57,10 @@ class NavigateToItemViewAction(private val menuItemName: String) : ViewAction { if (matchedMenuItem == null) { throw PerformException.Builder() - .withActionDescription(this.description) - .withViewDescription(HumanReadables.describe(view)) - .withCause(RuntimeException(getErrorMsg(navigationMenu, view))) - .build() + .withActionDescription(this.description) + .withViewDescription(HumanReadables.describe(view)) + .withCause(RuntimeException(getErrorMsg(navigationMenu, view))) + .build() } navigationMenu.performItemAction(matchedMenuItem, 0) } @@ -71,9 +71,10 @@ class NavigateToItemViewAction(private val menuItemName: String) : ViewAction { override fun getConstraints(): Matcher { return allOf( - isAssignableFrom(NavigationView::class.java), - withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE), - isDisplayingAtLeast(90)) + isAssignableFrom(NavigationView::class.java), + withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE), + isDisplayingAtLeast(90) + ) } private fun getErrorMsg(menu: Menu, view: View): String { diff --git a/FlowCrypt/src/androidTest/resources/ssl/README b/FlowCrypt/src/androidTest/resources/ssl/README index 04e03dc6ef..83dbd65357 100644 --- a/FlowCrypt/src/androidTest/resources/ssl/README +++ b/FlowCrypt/src/androidTest/resources/ssl/README @@ -15,4 +15,3 @@ openssl ca -config openssl-ca.cnf -days 3650 -out localhost-cert.pem -infiles lo -----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY----- - diff --git a/FlowCrypt/src/consumer/java/com/flowcrypt/email/util/FlavorSettings.kt b/FlowCrypt/src/consumer/java/com/flowcrypt/email/util/FlavorSettings.kt index 0c63e41032..557ed95277 100644 --- a/FlowCrypt/src/consumer/java/com/flowcrypt/email/util/FlavorSettings.kt +++ b/FlowCrypt/src/consumer/java/com/flowcrypt/email/util/FlavorSettings.kt @@ -5,7 +5,7 @@ package com.flowcrypt.email.util -import java.util.* +import java.util.Properties /** * @author Denis Bondarenko @@ -17,4 +17,4 @@ object FlavorSettings : EnvironmentSettings { override fun sslTrustedDomains(): List = emptyList() override fun getFlavorPropertiesForSession() = Properties() override fun isGMailAPIEnabled(): Boolean = false -} \ No newline at end of file +} diff --git a/FlowCrypt/src/debug/res/values/api_keys.xml b/FlowCrypt/src/debug/res/values/api_keys.xml index 44e66aed85..4b4434e065 100644 --- a/FlowCrypt/src/debug/res/values/api_keys.xml +++ b/FlowCrypt/src/debug/res/values/api_keys.xml @@ -6,4 +6,4 @@ msauth://com.flowcrypt.email.debug/vp2RH4JXIKnbbOr7J9BKkGmw8VE%3D /vp2RH4JXIKnbbOr7J9BKkGmw8VE= - \ No newline at end of file + diff --git a/FlowCrypt/src/debug/res/xml/network_security_config.xml b/FlowCrypt/src/debug/res/xml/network_security_config.xml index f4908835b6..85f79f8d6f 100644 --- a/FlowCrypt/src/debug/res/xml/network_security_config.xml +++ b/FlowCrypt/src/debug/res/xml/network_security_config.xml @@ -11,4 +11,4 @@ - \ No newline at end of file + diff --git a/FlowCrypt/src/dev/java/com/flowcrypt/email/util/FlavorSettings.kt b/FlowCrypt/src/dev/java/com/flowcrypt/email/util/FlavorSettings.kt index 0c63e41032..557ed95277 100644 --- a/FlowCrypt/src/dev/java/com/flowcrypt/email/util/FlavorSettings.kt +++ b/FlowCrypt/src/dev/java/com/flowcrypt/email/util/FlavorSettings.kt @@ -5,7 +5,7 @@ package com.flowcrypt.email.util -import java.util.* +import java.util.Properties /** * @author Denis Bondarenko @@ -17,4 +17,4 @@ object FlavorSettings : EnvironmentSettings { override fun sslTrustedDomains(): List = emptyList() override fun getFlavorPropertiesForSession() = Properties() override fun isGMailAPIEnabled(): Boolean = false -} \ No newline at end of file +} diff --git a/FlowCrypt/src/devTest/java/com/flowcrypt/email/util/FlavorSettings.kt b/FlowCrypt/src/devTest/java/com/flowcrypt/email/util/FlavorSettings.kt index b994d0ce12..f17b09fb3d 100644 --- a/FlowCrypt/src/devTest/java/com/flowcrypt/email/util/FlavorSettings.kt +++ b/FlowCrypt/src/devTest/java/com/flowcrypt/email/util/FlavorSettings.kt @@ -6,7 +6,7 @@ package com.flowcrypt.email.util import com.flowcrypt.email.api.email.JavaEmailConstants -import java.util.* +import java.util.Properties /** * @author Denis Bondarenko @@ -18,4 +18,4 @@ object FlavorSettings : EnvironmentSettings { override fun sslTrustedDomains(): List = emptyList() override fun getFlavorPropertiesForSession() = Properties() override fun isGMailAPIEnabled(): Boolean = false -} \ No newline at end of file +} diff --git a/FlowCrypt/src/enterprise/java/com/flowcrypt/email/util/FlavorSettings.kt b/FlowCrypt/src/enterprise/java/com/flowcrypt/email/util/FlavorSettings.kt index 81f6d66cc7..09574f3dd0 100644 --- a/FlowCrypt/src/enterprise/java/com/flowcrypt/email/util/FlavorSettings.kt +++ b/FlowCrypt/src/enterprise/java/com/flowcrypt/email/util/FlavorSettings.kt @@ -5,7 +5,7 @@ package com.flowcrypt.email.util -import java.util.* +import java.util.Properties /** * @author Denis Bondarenko @@ -17,4 +17,4 @@ object FlavorSettings : EnvironmentSettings { override fun sslTrustedDomains(): List = emptyList() override fun getFlavorPropertiesForSession() = Properties() override fun isGMailAPIEnabled(): Boolean = true -} \ No newline at end of file +} diff --git a/FlowCrypt/src/enterprise/res/mipmap-anydpi/ic_launcher.xml b/FlowCrypt/src/enterprise/res/mipmap-anydpi/ic_launcher.xml index 8b7128a1e3..d5f7297473 100644 --- a/FlowCrypt/src/enterprise/res/mipmap-anydpi/ic_launcher.xml +++ b/FlowCrypt/src/enterprise/res/mipmap-anydpi/ic_launcher.xml @@ -6,4 +6,4 @@ - \ No newline at end of file + diff --git a/FlowCrypt/src/enterprise/res/values/api_keys.xml b/FlowCrypt/src/enterprise/res/values/api_keys.xml index 0057e1b907..1e3c800243 100644 --- a/FlowCrypt/src/enterprise/res/values/api_keys.xml +++ b/FlowCrypt/src/enterprise/res/values/api_keys.xml @@ -6,4 +6,4 @@ msauth://com.flowcrypt.email.enterprise/gVgrJ%2BnS3FFmy0N1RePwMwAKI70%3D /gVgrJ+nS3FFmy0N1RePwMwAKI70= - \ No newline at end of file + diff --git a/FlowCrypt/src/enterpriseDebug/res/values/api_keys.xml b/FlowCrypt/src/enterpriseDebug/res/values/api_keys.xml index bae37725c1..c878985653 100644 --- a/FlowCrypt/src/enterpriseDebug/res/values/api_keys.xml +++ b/FlowCrypt/src/enterpriseDebug/res/values/api_keys.xml @@ -6,4 +6,4 @@ msauth://com.flowcrypt.emai.enterprise.debug/vp2RH4JXIKnbbOr7J9BKkGmw8VE%3D /vp2RH4JXIKnbbOr7J9BKkGmw8VE= - \ No newline at end of file + diff --git a/FlowCrypt/src/main/AndroidManifest.xml b/FlowCrypt/src/main/AndroidManifest.xml index fcfa60f0df..aebb3bd8ad 100644 --- a/FlowCrypt/src/main/AndroidManifest.xml +++ b/FlowCrypt/src/main/AndroidManifest.xml @@ -325,4 +325,4 @@ - \ No newline at end of file + diff --git a/FlowCrypt/src/main/assets/html/license.htm b/FlowCrypt/src/main/assets/html/license.htm index fa84c0b0e1..344ecfc5ab 100644 --- a/FlowCrypt/src/main/assets/html/license.htm +++ b/FlowCrypt/src/main/assets/html/license.htm @@ -69,4 +69,4 @@

Work attributions

- \ No newline at end of file + diff --git a/FlowCrypt/src/main/assets/html/no_connection.htm b/FlowCrypt/src/main/assets/html/no_connection.htm index be75e9864f..f0ea0f40ab 100644 --- a/FlowCrypt/src/main/assets/html/no_connection.htm +++ b/FlowCrypt/src/main/assets/html/no_connection.htm @@ -21,4 +21,4 @@ src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAC01BMVEUAAAAAAACAgIBVVVWAgIBmZmaAgIBtbW2AgIBxcXGAgIB0dHSAgIB2dnZtbW13d3dwcHB4eHhxcXF5eXlzc3N5eXl0dHR6enp1dXV2dnZxcXF2dnZycnJ3d3dzc3N4eHh0dHR4eHh1dXV4eHh1dXVycnJ2dnZzc3N2dnZzc3N3d3d0dHR3d3d0dHR3d3dycnJ1dXV2dnZzc3N2dnZ0dHR2dnZ0dHR1dXV3d3d1dXVzc3N0dHR2dnZ0dHR2dnZ0dHR2dnZ1dXV3d3d1dXVzc3N1dXV0dHR1dXV0dHR2dnZ2dnZ0dHR1dXV2dnZ1dXV0dHR1dXV0dHR1dXV0dHR2dnZ0dHR2dnZ1dXV2dnZ1dXV2dnZ1dXV0dHR1dXV0dHR2dnZ0dHR2dnZ1dXV2dnZ1dXV2dnZ1dXV0dHR1dXV0dHR1dXV0dHR2dnZ1dXV2dnZ1dXV2dnZ1dXV2dnZ1dXV0dHR1dXV0dHR1dXV0dHR2dnZ1dXV2dnZ1dXV1dXV0dHR1dXV0dHR1dXV1dXV2dnZ2dnZ1dXV2dnZ1dXV0dHR1dXV0dHR1dXV1dXV1dXV1dXV1dXV2dnZ1dXV0dHR1dXV0dHR1dXV0dHR1dXV1dXV1dXV2dnZ1dXV2dnZ1dXV0dHR1dXV0dHR1dXV1dXV1dXV1dXV1dXV1dXV2dnZ1dXV2dnZ1dXV0dHR1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV2dnZ0dHR1dXV0dHR1dXV1dXV1dXV1dXV1dXV1dXV2dnZ2dnZ1dXV0dHR1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV0dHR1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV2dnZ1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV0dHR1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXX///91sclTAAAA73RSTlMAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGhscHR4fICEiIyQlJicoKSorLC0uLzEyNDU2Nzg5Ozw9PkBBQkNERUZHSElKS0xNTlBRU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gIGCg4WIiYqLjI2PkJGSk5SVlpeYmZucnZ6foKGipKWmp6ipqqusra6vsLGys7S1tre4ubq7vL2+v8DBw8TFxsfIycrLzM7P0NHS09TV1tfY2tvc3d7f4OHi4+Tl5ufo6err7O3u7/Dx8vP09fb3+Pn6+/z9/v5PZAIAAAABYktHRPA1uO9UAAAIaUlEQVR42u2c618VRRjHnwOCKCgBligoQYqJhKikmKbdscwLoYkoqGFl3vNSkbe8hKZIGZppYlmIiXdFNM2M8oIaoaZk4hVR9HA48y/0QlSYmT1nd2fmsHs+83vJ7jx7vjwzs88888wCSElJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSbmrLO/46GvYKiZh7Jz5K7I3rMtePG/6u69HNWtcji9QgVYSz66pS/ddR4TKi1YmRzYeB9JG0mn8pmvIgSryp3VsBI5lCCGEtqvtFVEZJ5EKlWbGW1zvD6TWJwGTTiDVOjM1qBE41JB0/eo20qTqnO6u53BK0nMb0qGDL7icwzHJswVIp/b0dDWHA5I239qRfuV3FsyxlHgkfe7ymnATMck630ckyDLKI6k+CS1DrCrpLRBkvF0tSRg7iT1LYPiSVkt5IrV3tStlJkEnO7sLSeVQcSTjXNm7EMpsIowk1aU+QfnNhZGMdi3J4VbCSMbo713WI6tnDInvGOAP3gHh0T2Hzd1QfNcZyYlQ1454pyQ1hTN6Ue7x6TNnv9Uhybn2rh0nDkls25L9le21SN5d64DkdGvXjhNlkvKMNs4shs74R5mk+DFhJKM0kJSO9lJj0jv1jCJJkbi5K0U1SSvVrwLPpLNKJJvErYJHqp6FNahZhtIk9iG4lqSANfqO3E0HsQlcNybWCPAJWCbQJ+OrT4ojGWET4RPodZ5KcshTHMnbYkiC6N1rqsCV1lAhvQu8v6OB3O1sPhLLYmqiSGDngmFiehfMo5G8JzIhMUSMT2Apxez1QBOSeORSzH4mkMMndAkS0rt8Cimp4XYiEMIGzt1SckMpOmInCb5EWl3NG+KJ5NyrTlZ27CT9ySCothNPiuDph2pVrLbZSeaSRrP45X/7b7SqzBswk3j+Rti8zWniajLytIYMCDNJD9Lz03lgeAw+pS2XwzwLryRMXvBi5+j7p+asFKtPAi8TJt9gxfDPrEXaxeqTyYTFdYwcA8v1ZQoZfeJbgRu8xZSIaJqpO+fJ6JPZhMFBDNZCfmHI3rKRtCTKPnL1G+tXwZSHZutd+P4rqmqqO761IjYx+SSOMNdLp6XhNcx7A0wkJbi1mfrspNci1KgkxHAv0GVmHOIihnESSWwt6tmPG2Bz+PvuFOfOnTYmaXADZdj5klzAbaXHaA4dezio7rlbMLUbPa+RzpfkG4q1qqMrU6I8VJto/59ypn9sgINxxZUkRek3/Jv9sre6oP2AgoXa72MdtxzPkyTcQd++sfxpfSs0hBBCW53n/HiSWKoclnrsSnBmoDd9oF8coebpaXZ+s/DvTqbEQ30cNvejZ8XXt1D3dI4+We90ds8Lc9B8PrXocKzqx/MjyXD+nrqVrrg5F3mPcv+1eA3P50YyWlUBYYhC6620+S5G0w/gNU6GqAoeKvpSG79KufXSUxp/ASefvKKyfjCd1riIvPFmrOb/JR+fxKuN6Baoamvrp2OccvFJjOrYdAkx5PPJm2bregfwIIlSH2Uvx5p2IR+/wwMai0QDCJrVsCm5h1cZojd4ZR8nWkDswxtkjy8SN0zWv8Rj9okWEFQdV39ngrh8nCXlyjUWhoCQuOSFh5UXfKX1Yqgcrlkx3iT3M7gpe5WSCWse9SziHFGJBxiNBCBqrUJ+Z/CDO2KJSyNZU+BCSKBLIRXkgl/d9UnEO51931wMiSXtDo1kXt3lzfiFVRx2icSQQDRtC606/P4QIfLGfcG4JI//SjH7NX2xX8mnQl0QiR8lvr3Xlho1bwE+4rmOrz8TFysUe7yP/3UKJxBRPgkjj53e9AWA5fhf+/ACEeWTBNLsWwCwHf9jG24gonxCZlU3AwBeb1DJs3pYjE9aExOtNQgArwo4BjwlxiczCZPDAfAY/gBXEDE+IfdMvwTAD0Nu5wsixicLicMaAHiovwlMQBJNGGwLePL7ZzADCVEokwD47k4hdxAR44RIM0wE/EDKUf4gAnzyGm5tBRzF/lIOZiAJxo3tBGLZ1dIUJDeI1x/xvu8GZiDBO1IZzOK+YncJyR7M0hUYhBvPEQPCee7KwxdX5LvlPJiBZAtmpwZ8iCyesI/78OxdB/FtRYDDuOlPwAQkeNB+mbKf+5fF+CQWPP49DvAiYTkeDE8SgdvYBdCc2JnOA8OTJNFyW3uI7ZNnDE9CFPROA4BUwu5GMDiJxzncwAAAaEmmhvuJJOHwPulLtA8GACBPNJZ4G9snq/DWZ+nBPUKfgpFJ2t6h71s1Ib8EYnveyCRZRNvE+xfGUCpqgo1LEkEUi1vrClG9zpFWj7QAg454D/K89cMdhAkUqzu8DeqTaWS7YQ+uNb9IsfqjjyFJ4sgauUuPWiXSdhn3+Ruwd3WgHCGtfxBgJ43kjwjD+SSEMpyr6tecd6B+2qMy0WA+iS6jtPi8wS1z6HUFq4KM5JMBt2hnDxqesvZSqCi/kuphFBI/+plCrGgLQq8olK0cS/I0BMlzZdSfd4p4TSQofv7yzMRgA5AofOeOEqnPUy7wsm1NizAmyRraij7HYbXa2XUfDY0ND/Q2FMlxX5pJzx+QYaTui32VCgdKmu03F4n9TSU3++81DomK3vWxcodtusFEPlnkaOh5ZpmGZLGTWWSK1Ry9a5HT+bD73ybwSY2aD1v4bzQ8yRV1qTfLqApj96481V8KDci0GdknWhR3wMg+0aT4fDfxCUDPPJt7+AQgcEyRe/gEAKIz9lvdwScAAL4vLdh13i1IAAB8YxM/mD0/e22uaG22CyZxmQRVPksSSSJJDClqlugncA+f3EsAtyAxKQdBYloOjMTEHA1ITM1Rj8TkHA9JTM9RR+IGHABpdvfgAEirdg8OgBCQkpKSkpKSkpKSkpIyrv4HPZOVUx05lUsAAAAASUVORK5CYII=" style="display: block; margin-left: auto; margin-right: auto;"/>

No connection

- \ No newline at end of file + diff --git a/FlowCrypt/src/main/assets/html/privacy.htm b/FlowCrypt/src/main/assets/html/privacy.htm index dc55d9bfcb..f147716000 100644 --- a/FlowCrypt/src/main/assets/html/privacy.htm +++ b/FlowCrypt/src/main/assets/html/privacy.htm @@ -203,4 +203,4 @@

Feedback

and also mentioned in project's changelog if/when such changes occur.

Please send me your feedback or requests for clarification at human@flowcrypt.com

- \ No newline at end of file + diff --git a/FlowCrypt/src/main/assets/html/sources.htm b/FlowCrypt/src/main/assets/html/sources.htm index 0eec2223aa..e663749928 100644 --- a/FlowCrypt/src/main/assets/html/sources.htm +++ b/FlowCrypt/src/main/assets/html/sources.htm @@ -14,4 +14,4 @@

FlowCrypt Source Code

Please send me your questions to human@flowcrypt.com

- \ No newline at end of file + diff --git a/FlowCrypt/src/main/assets/html/terms.htm b/FlowCrypt/src/main/assets/html/terms.htm index 2b2830249d..3c7c5672d6 100644 --- a/FlowCrypt/src/main/assets/html/terms.htm +++ b/FlowCrypt/src/main/assets/html/terms.htm @@ -25,4 +25,4 @@

FlowCrypt Terms of Use

Please send me your questions to human@flowcrypt.com

- \ No newline at end of file + diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/Constants.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/Constants.kt index c5e1337224..140e1b5afd 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/Constants.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/Constants.kt @@ -44,7 +44,8 @@ class Constants { /** * The preference keys. */ - const val PREF_KEY_IS_WRITE_LOGS_TO_FILE_ENABLED = "preferences_key_is_write_logs_to_file_enabled" + const val PREF_KEY_IS_WRITE_LOGS_TO_FILE_ENABLED = + "preferences_key_is_write_logs_to_file_enabled" const val PREF_KEY_IS_ACRA_ENABLED = "pref_key_is_acra_enabled" const val PREF_KEY_IS_MAIL_DEBUG_ENABLED = "preferences_key_is_mail_debug_enabled" const val PREF_KEY_IS_HTTP_LOG_ENABLED = "pref_key_is_http_log_enabled" @@ -92,11 +93,49 @@ class Constants { const val PGP_FILE_EXT = ".pgp" - val PASSWORD_WEAK_WORDS = arrayOf("crypt", "up", "cryptup", "flow", "flowcrypt", "encryption", "pgp", "email", - "set", "backup", "passphrase", "best", "pass", "phrases", "are", "long", "and", "have", "several", "words", - "in", "them", "Best pass phrases are long", "have several words", "in them", "bestpassphrasesarelong", - "haveseveralwords", "inthem", "Loss of this pass phrase", "cannot be recovered", "Note it down", "on a paper", - "lossofthispassphrase", "cannotberecovered", "noteitdown", "onapaper", "setpassword", "set password", - "set pass word", "setpassphrase", "set pass phrase", "set passphrase") + val PASSWORD_WEAK_WORDS = arrayOf( + "crypt", + "up", + "cryptup", + "flow", + "flowcrypt", + "encryption", + "pgp", + "email", + "set", + "backup", + "passphrase", + "best", + "pass", + "phrases", + "are", + "long", + "and", + "have", + "several", + "words", + "in", + "them", + "Best pass phrases are long", + "have several words", + "in them", + "bestpassphrasesarelong", + "haveseveralwords", + "inthem", + "Loss of this pass phrase", + "cannot be recovered", + "Note it down", + "on a paper", + "lossofthispassphrase", + "cannotberecovered", + "noteitdown", + "onapaper", + "setpassword", + "set password", + "set pass word", + "setpassphrase", + "set pass phrase", + "set passphrase" + ) } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt index 60e373ef54..6fe2000d84 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/FlowCryptApplication.kt @@ -30,7 +30,8 @@ import org.acra.config.httpSender import org.acra.data.StringFormat import org.acra.ktx.initAcra import org.acra.sender.HttpSender -import java.util.* +import java.util.Calendar +import java.util.Locale import java.util.concurrent.TimeUnit /** diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/accounts/FlowcryptAccountAuthenticator.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/accounts/FlowcryptAccountAuthenticator.kt index e1e6489ad4..364732dbdb 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/accounts/FlowcryptAccountAuthenticator.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/accounts/FlowcryptAccountAuthenticator.kt @@ -33,15 +33,29 @@ class FlowcryptAccountAuthenticator(val context: Context) : AbstractAccountAuthe return BuildConfig.APPLICATION_ID + ".auth" + if (authTokenType.isNullOrEmpty()) "" else ".$authTokenType" } - override fun confirmCredentials(response: AccountAuthenticatorResponse?, account: Account?, options: Bundle?): Bundle { + override fun confirmCredentials( + response: AccountAuthenticatorResponse?, + account: Account?, + options: Bundle? + ): Bundle { return Bundle() } - override fun updateCredentials(response: AccountAuthenticatorResponse?, account: Account?, authTokenType: String?, options: Bundle?): Bundle { + override fun updateCredentials( + response: AccountAuthenticatorResponse?, + account: Account?, + authTokenType: String?, + options: Bundle? + ): Bundle { return Bundle() } - override fun getAuthToken(response: AccountAuthenticatorResponse?, account: Account?, authTokenType: String?, options: Bundle?): Bundle { + override fun getAuthToken( + response: AccountAuthenticatorResponse?, + account: Account?, + authTokenType: String?, + options: Bundle? + ): Bundle { account ?: return Bundle().apply { putInt(AccountManager.KEY_ERROR_CODE, AccountManager.ERROR_CODE_BAD_ARGUMENTS) putString(AccountManager.KEY_ERROR_MESSAGE, "Should provided non-null account") @@ -66,7 +80,10 @@ class FlowcryptAccountAuthenticator(val context: Context) : AbstractAccountAuthe if (encryptedRefreshToken.isNullOrEmpty()) { return Bundle().apply { putInt(AccountManager.KEY_ERROR_CODE, AccountManager.ERROR_CODE_BAD_ARGUMENTS) - putString(AccountManager.KEY_ERROR_MESSAGE, context.getString(R.string.refrech_token_was_corrupted)) + putString( + AccountManager.KEY_ERROR_MESSAGE, + context.getString(R.string.refrech_token_was_corrupted) + ) } } try { @@ -77,8 +94,16 @@ class FlowcryptAccountAuthenticator(val context: Context) : AbstractAccountAuthe val tokenResponse = apiResponse.body() authToken = KeyStoreCryptoManager.encrypt(tokenResponse?.accessToken) accountManager.setAuthToken(account, authTokenType, authToken) - accountManager.setUserData(account, KEY_REFRESH_TOKEN, KeyStoreCryptoManager.encrypt(tokenResponse?.refreshToken)) - accountManager.setUserData(account, KEY_EXPIRES_AT, OAuth2Helper.getExpiresAtTime(tokenResponse?.expiresIn).toString()) + accountManager.setUserData( + account, + KEY_REFRESH_TOKEN, + KeyStoreCryptoManager.encrypt(tokenResponse?.refreshToken) + ) + accountManager.setUserData( + account, + KEY_EXPIRES_AT, + OAuth2Helper.getExpiresAtTime(tokenResponse?.expiresIn).toString() + ) } else return Bundle().apply { //via clearing the current token we force the token updating in the next call accountManager.setAuthToken(account, authTokenType, null) @@ -96,7 +121,7 @@ class FlowcryptAccountAuthenticator(val context: Context) : AbstractAccountAuthe } val errorMsg = errorResponse?.errorDescription - ?: context.getString(R.string.could_not_fetch_access_token) + ?: context.getString(R.string.could_not_fetch_access_token) putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg) } } catch (e: Exception) { @@ -119,15 +144,28 @@ class FlowcryptAccountAuthenticator(val context: Context) : AbstractAccountAuthe return genBundleToAddNewAccount(response).apply { options?.let { putAll(options) } } } - override fun hasFeatures(response: AccountAuthenticatorResponse?, account: Account?, features: Array?): Bundle { + override fun hasFeatures( + response: AccountAuthenticatorResponse?, + account: Account?, + features: Array? + ): Bundle { return Bundle() } - override fun editProperties(response: AccountAuthenticatorResponse?, accountType: String?): Bundle { + override fun editProperties( + response: AccountAuthenticatorResponse?, + accountType: String? + ): Bundle { return Bundle() } - override fun addAccount(response: AccountAuthenticatorResponse?, accountType: String?, authTokenType: String?, requiredFeatures: Array?, options: Bundle?): Bundle { + override fun addAccount( + response: AccountAuthenticatorResponse?, + accountType: String?, + authTokenType: String?, + requiredFeatures: Array?, + options: Bundle? + ): Bundle { if (ACCOUNT_TYPE != accountType) { throw IllegalArgumentException("Request to the wrong authenticator!") } @@ -146,18 +184,23 @@ class FlowcryptAccountAuthenticator(val context: Context) : AbstractAccountAuthe } } - override fun getAccountRemovalAllowed(response: AccountAuthenticatorResponse?, account: Account?): Bundle { + override fun getAccountRemovalAllowed( + response: AccountAuthenticatorResponse?, + account: Account? + ): Bundle { val bundle = super.getAccountRemovalAllowed(response, account) if (bundle?.containsKey(AccountManager.KEY_BOOLEAN_RESULT) == true) { val isRemovalAllowed = bundle.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false) if (isRemovalAllowed) { return Bundle().apply { - putParcelable(AccountManager.KEY_INTENT, Intent(context, EmailManagerActivity::class.java).apply { - action = EmailManagerActivity.ACTION_REMOVE_ACCOUNT_VIA_SYSTEM_SETTINGS - putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response) - putExtra(EmailManagerActivity.KEY_ACCOUNT, account) - }) + putParcelable( + AccountManager.KEY_INTENT, + Intent(context, EmailManagerActivity::class.java).apply { + action = EmailManagerActivity.ACTION_REMOVE_ACCOUNT_VIA_SYSTEM_SETTINGS + putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response) + putExtra(EmailManagerActivity.KEY_ACCOUNT, account) + }) } } } @@ -174,4 +217,4 @@ class FlowcryptAccountAuthenticator(val context: Context) : AbstractAccountAuthe const val ACCOUNT_TYPE = BuildConfig.APPLICATION_ID const val AUTH_TOKEN_TYPE_EMAIL = "email" } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/accounts/FlowcryptAuthenticatorService.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/accounts/FlowcryptAuthenticatorService.kt index 996ecaf146..1f508da23e 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/accounts/FlowcryptAuthenticatorService.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/accounts/FlowcryptAuthenticatorService.kt @@ -26,4 +26,4 @@ class FlowcryptAuthenticatorService : Service() { override fun onBind(intent: Intent?): IBinder? { return authenticator.iBinder } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/EmailProviderSettingsHelper.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/EmailProviderSettingsHelper.kt index 64f02b3e32..b2838f2872 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/EmailProviderSettingsHelper.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/EmailProviderSettingsHelper.kt @@ -25,7 +25,8 @@ object EmailProviderSettingsHelper { private const val PROVIDER_LIVE = "live.com" private const val IMAP_SERVER_MICROSOFT = "outlook.office365.com" private const val SMTP_SERVER_MICROSOFT = "smtp.office365.com" - private const val FAQ_URL_MICROSOFT = "https://support.microsoft.com/en-us/office/pop-imap-and-smtp-settings-for-outlook-com-d088b986-291d-42b8-9564-9c414e2aa040" + private const val FAQ_URL_MICROSOFT = + "https://support.microsoft.com/en-us/office/pop-imap-and-smtp-settings-for-outlook-com-d088b986-291d-42b8-9564-9c414e2aa040" /*********************** Yahoo **********************/ private const val PROVIDER_YAHOO = "yahoo.com" @@ -43,7 +44,8 @@ object EmailProviderSettingsHelper { private const val PROVIDER_AOL = "aol.com" private const val IMAP_SERVER_AOL = "imap.aol.com" private const val SMTP_SERVER_AOL = "smtp.aol.com" - private const val FAQ_URL_AOL = "https://help.aol.com/articles/how-do-i-use-other-email-applications-to-send-and-receive-my-aol-mail" + private const val FAQ_URL_AOL = + "https://help.aol.com/articles/how-do-i-use-other-email-applications-to-send-and-receive-my-aol-mail" /*********************** UKR-NET **********************/ private const val PROVIDER_UKR_NET = "ukr.net" @@ -65,14 +67,26 @@ object EmailProviderSettingsHelper { } return when { - PROVIDER_OUTLOOK.equals(EmailUtil.getDomain(email), true) -> getOutlookSettings(email, password) - PROVIDER_HOTMAIL.equals(EmailUtil.getDomain(email), true) -> getOutlookSettings(email, password) + PROVIDER_OUTLOOK.equals(EmailUtil.getDomain(email), true) -> getOutlookSettings( + email, + password + ) + PROVIDER_HOTMAIL.equals(EmailUtil.getDomain(email), true) -> getOutlookSettings( + email, + password + ) PROVIDER_LIVE.equals(EmailUtil.getDomain(email), true) -> getOutlookSettings(email, password) PROVIDER_YAHOO.equals(EmailUtil.getDomain(email), true) -> getYahooSettings(email, password) PROVIDER_ICLOUD.equals(EmailUtil.getDomain(email), true) -> getICloudSettings(email, password) PROVIDER_AOL.equals(EmailUtil.getDomain(email), true) -> getAolSettings(email, password) - PROVIDER_UKR_NET.equals(EmailUtil.getDomain(email), true) -> getUkrNetSettings(email, password) - PROVIDER_TESTS.equals(EmailUtil.getDomain(email), true) -> getTestProviderSettings(email, password) + PROVIDER_UKR_NET.equals(EmailUtil.getDomain(email), true) -> getUkrNetSettings( + email, + password + ) + PROVIDER_TESTS.equals(EmailUtil.getDomain(email), true) -> getTestProviderSettings( + email, + password + ) else -> { null @@ -88,108 +102,108 @@ object EmailProviderSettingsHelper { private fun getOutlookSettings(email: String, password: String): AuthCredentials { return AuthCredentials( - email = email, - username = email, - password = password, - imapServer = IMAP_SERVER_MICROSOFT, - imapPort = JavaEmailConstants.SSL_IMAP_PORT, - imapOpt = SecurityType.Option.SSL_TLS, - smtpServer = SMTP_SERVER_MICROSOFT, - smtpPort = JavaEmailConstants.STARTTLS_SMTP_PORT, - smtpOpt = SecurityType.Option.STARTLS, - hasCustomSignInForSmtp = true, - smtpSigInUsername = email, - smtpSignInPassword = password, - faqUrl = FAQ_URL_MICROSOFT + email = email, + username = email, + password = password, + imapServer = IMAP_SERVER_MICROSOFT, + imapPort = JavaEmailConstants.SSL_IMAP_PORT, + imapOpt = SecurityType.Option.SSL_TLS, + smtpServer = SMTP_SERVER_MICROSOFT, + smtpPort = JavaEmailConstants.STARTTLS_SMTP_PORT, + smtpOpt = SecurityType.Option.STARTLS, + hasCustomSignInForSmtp = true, + smtpSigInUsername = email, + smtpSignInPassword = password, + faqUrl = FAQ_URL_MICROSOFT ) } private fun getYahooSettings(email: String, password: String): AuthCredentials { return AuthCredentials( - email = email, - username = email, - password = password, - imapServer = IMAP_SERVER_YAHOO, - imapPort = JavaEmailConstants.SSL_IMAP_PORT, - imapOpt = SecurityType.Option.SSL_TLS, - smtpServer = SMTP_SERVER_YAHOO, - smtpPort = JavaEmailConstants.SSL_SMTP_PORT, - smtpOpt = SecurityType.Option.SSL_TLS, - hasCustomSignInForSmtp = true, - smtpSigInUsername = email, - smtpSignInPassword = password, - faqUrl = FAQ_URL_YAHOO + email = email, + username = email, + password = password, + imapServer = IMAP_SERVER_YAHOO, + imapPort = JavaEmailConstants.SSL_IMAP_PORT, + imapOpt = SecurityType.Option.SSL_TLS, + smtpServer = SMTP_SERVER_YAHOO, + smtpPort = JavaEmailConstants.SSL_SMTP_PORT, + smtpOpt = SecurityType.Option.SSL_TLS, + hasCustomSignInForSmtp = true, + smtpSigInUsername = email, + smtpSignInPassword = password, + faqUrl = FAQ_URL_YAHOO ) } private fun getICloudSettings(email: String, password: String): AuthCredentials { return AuthCredentials( - email = email, - username = email, - password = password, - imapServer = IMAP_SERVER_ICLOUD, - imapPort = JavaEmailConstants.SSL_IMAP_PORT, - imapOpt = SecurityType.Option.SSL_TLS, - smtpServer = SMTP_SERVER_ICLOUD, - smtpPort = JavaEmailConstants.STARTTLS_SMTP_PORT, - smtpOpt = SecurityType.Option.STARTLS, - hasCustomSignInForSmtp = true, - smtpSigInUsername = email, - smtpSignInPassword = password, - faqUrl = FAQ_URL_ICLOUD + email = email, + username = email, + password = password, + imapServer = IMAP_SERVER_ICLOUD, + imapPort = JavaEmailConstants.SSL_IMAP_PORT, + imapOpt = SecurityType.Option.SSL_TLS, + smtpServer = SMTP_SERVER_ICLOUD, + smtpPort = JavaEmailConstants.STARTTLS_SMTP_PORT, + smtpOpt = SecurityType.Option.STARTLS, + hasCustomSignInForSmtp = true, + smtpSigInUsername = email, + smtpSignInPassword = password, + faqUrl = FAQ_URL_ICLOUD ) } private fun getAolSettings(email: String, password: String): AuthCredentials { return AuthCredentials( - email = email, - username = email, - password = password, - imapServer = IMAP_SERVER_AOL, - imapPort = JavaEmailConstants.SSL_IMAP_PORT, - imapOpt = SecurityType.Option.SSL_TLS, - smtpServer = SMTP_SERVER_AOL, - smtpPort = JavaEmailConstants.SSL_SMTP_PORT, - smtpOpt = SecurityType.Option.SSL_TLS, - hasCustomSignInForSmtp = true, - smtpSigInUsername = email, - smtpSignInPassword = password, - faqUrl = FAQ_URL_AOL + email = email, + username = email, + password = password, + imapServer = IMAP_SERVER_AOL, + imapPort = JavaEmailConstants.SSL_IMAP_PORT, + imapOpt = SecurityType.Option.SSL_TLS, + smtpServer = SMTP_SERVER_AOL, + smtpPort = JavaEmailConstants.SSL_SMTP_PORT, + smtpOpt = SecurityType.Option.SSL_TLS, + hasCustomSignInForSmtp = true, + smtpSigInUsername = email, + smtpSignInPassword = password, + faqUrl = FAQ_URL_AOL ) } private fun getUkrNetSettings(email: String, password: String): AuthCredentials { return AuthCredentials( - email = email, - username = email, - password = password, - imapServer = IMAP_SERVER_UKR_NET, - imapPort = JavaEmailConstants.SSL_IMAP_PORT, - imapOpt = SecurityType.Option.SSL_TLS, - smtpServer = SMTP_SERVER_UKR_NET, - smtpPort = JavaEmailConstants.SSL_SMTP_PORT, - smtpOpt = SecurityType.Option.SSL_TLS, - hasCustomSignInForSmtp = true, - smtpSigInUsername = email, - smtpSignInPassword = password, - faqUrl = FAQ_URL_UKR_NET + email = email, + username = email, + password = password, + imapServer = IMAP_SERVER_UKR_NET, + imapPort = JavaEmailConstants.SSL_IMAP_PORT, + imapOpt = SecurityType.Option.SSL_TLS, + smtpServer = SMTP_SERVER_UKR_NET, + smtpPort = JavaEmailConstants.SSL_SMTP_PORT, + smtpOpt = SecurityType.Option.SSL_TLS, + hasCustomSignInForSmtp = true, + smtpSigInUsername = email, + smtpSignInPassword = password, + faqUrl = FAQ_URL_UKR_NET ) } private fun getTestProviderSettings(email: String, password: String): AuthCredentials { return AuthCredentials( - email = email, - username = email, - password = password, - imapServer = IMAP_SERVER_TESTS, - imapPort = JavaEmailConstants.SSL_IMAP_PORT, - imapOpt = SecurityType.Option.SSL_TLS, - smtpServer = SMTP_SERVER_TESTS, - smtpPort = JavaEmailConstants.STARTTLS_SMTP_PORT, - smtpOpt = SecurityType.Option.STARTLS, - hasCustomSignInForSmtp = true, - smtpSigInUsername = email, - smtpSignInPassword = password, + email = email, + username = email, + password = password, + imapServer = IMAP_SERVER_TESTS, + imapPort = JavaEmailConstants.SSL_IMAP_PORT, + imapOpt = SecurityType.Option.SSL_TLS, + smtpServer = SMTP_SERVER_TESTS, + smtpPort = JavaEmailConstants.STARTTLS_SMTP_PORT, + smtpOpt = SecurityType.Option.STARTLS, + hasCustomSignInForSmtp = true, + smtpSigInUsername = email, + smtpSignInPassword = password, ) } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/EmailUtil.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/EmailUtil.kt index d356359a13..4e1791b903 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/EmailUtil.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/EmailUtil.kt @@ -99,22 +99,22 @@ class EmailUtil { private const val HTML_EMAIL_INTRO_TEMPLATE_HTM = "html/email_intro.template.htm" private val ALLOWED_FILE_NAMES = arrayOf( - "PGPexch.htm.pgp", - "PGPMIME version identification", - "Version.txt", - "PGPMIME Versions Identification", - "signature.asc", - "msg.asc", - "message", - "message.asc", - "encrypted.asc", - "encrypted.eml.pgp", - "Message.pgp" + "PGPexch.htm.pgp", + "PGPMIME version identification", + "Version.txt", + "PGPMIME Versions Identification", + "signature.asc", + "msg.asc", + "message", + "message.asc", + "encrypted.asc", + "encrypted.eml.pgp", + "Message.pgp" ) private val KEYS_EXTENSIONS = arrayOf( - "asc", - "key" + "asc", + "key" ) /** @@ -165,8 +165,12 @@ class EmailUtil { attInfo.type = GeneralUtil.getFileMimeTypeFromUri(context, uri) attInfo.id = generateContentId() - val cursor = context.contentResolver.query(uri, arrayOf(OpenableColumns.DISPLAY_NAME, - OpenableColumns.SIZE), null, null, null) + val cursor = context.contentResolver.query( + uri, arrayOf( + OpenableColumns.DISPLAY_NAME, + OpenableColumns.SIZE + ), null, null, null + ) if (cursor != null) { if (cursor.moveToFirst()) { val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME) @@ -198,13 +202,13 @@ class EmailUtil { */ fun genAttInfoFromPubKey(pgpKeyDetails: PgpKeyDetails?): AttachmentInfo? { if (pgpKeyDetails != null) { - val fileName = "0x" + pgpKeyDetails.fingerprint?.toUpperCase(Locale.getDefault()) + ".asc" + val fileName = "0x" + pgpKeyDetails.fingerprint.toUpperCase(Locale.getDefault()) + ".asc" return if (!TextUtils.isEmpty(pgpKeyDetails.publicKey)) { val attachmentInfo = AttachmentInfo() attachmentInfo.name = fileName - attachmentInfo.encodedSize = pgpKeyDetails.publicKey?.length?.toLong() ?: 0 + attachmentInfo.encodedSize = pgpKeyDetails.publicKey.length.toLong() attachmentInfo.rawData = pgpKeyDetails.publicKey attachmentInfo.type = Constants.MIME_TYPE_PGP_KEY attachmentInfo.email = pgpKeyDetails.primaryPgpContact.email @@ -245,7 +249,11 @@ class EmailUtil { * @return Generated [Message] object. * @throws Exception will occur when generate this message. */ - fun genMsgWithAllPrivateKeys(context: Context, account: AccountEntity, session: Session): Message { + fun genMsgWithAllPrivateKeys( + context: Context, + account: AccountEntity, + session: Session + ): Message { val keys = SecurityUtils.genPrivateKeysBackup(context, account) val multipart = MimeMultipart() @@ -269,7 +277,12 @@ class EmailUtil { * @return Generated [Message] object. * @throws Exception will occur when generate this message. */ - fun genMsgWithPrivateKeys(context: Context, account: AccountEntity, sess: Session, bodyPart: MimeBodyPart): Message { + fun genMsgWithPrivateKeys( + context: Context, + account: AccountEntity, + sess: Session, + bodyPart: MimeBodyPart + ): Message { val multipart = MimeMultipart() multipart.addBodyPart(getBodyPartWithBackupText(context)) bodyPart.contentID = generateContentId() @@ -292,7 +305,11 @@ class EmailUtil { fun getGmailAccountToken(context: Context, accountEntity: AccountEntity): String { val account: Account = accountEntity.account - return GoogleAuthUtil.getToken(context, account, JavaEmailConstants.OAUTH2 + GmailScopes.MAIL_GOOGLE_COM) + return GoogleAuthUtil.getToken( + context, + account, + JavaEmailConstants.OAUTH2 + GmailScopes.MAIL_GOOGLE_COM + ) } /** @@ -303,8 +320,9 @@ class EmailUtil { */ fun hasEnabledDebug(context: Context): Boolean { return GeneralUtil.isDebugBuild() && SharedPreferencesHelper.getBoolean( - PreferenceManager.getDefaultSharedPreferences(context.applicationContext), - Constants.PREF_KEY_IS_MAIL_DEBUG_ENABLED, BuildConfig.IS_MAIL_DEBUG_ENABLED) + PreferenceManager.getDefaultSharedPreferences(context.applicationContext), + Constants.PREF_KEY_IS_MAIL_DEBUG_ENABLED, BuildConfig.IS_MAIL_DEBUG_ENABLED + ) } /** @@ -354,7 +372,11 @@ class EmailUtil { * @param msgs The array of incoming messages. * @return A list of UID of the local messages which will be removed. */ - fun genDeleteCandidates(localUIDs: Collection, folder: IMAPFolder, msgs: Array): Collection { + fun genDeleteCandidates( + localUIDs: Collection, + folder: IMAPFolder, + msgs: Array + ): Collection { val uidListDeleteCandidates = HashSet(localUIDs) val uidList = HashSet() try { @@ -380,7 +402,11 @@ class EmailUtil { * @param msgs The array of incoming messages. * @return The generated array. */ - fun genNewCandidates(localUIDs: Collection, folder: IMAPFolder, msgs: Array): Array { + fun genNewCandidates( + localUIDs: Collection, + folder: IMAPFolder, + msgs: Array + ): Array { val newCandidates = mutableListOf() try { for (msg in msgs) { @@ -406,7 +432,11 @@ class EmailUtil { * @param msgs The array of incoming messages. * @return An array of the messages which are candidates for updating iin the local database. */ - fun genUpdateCandidates(map: Map, folder: IMAPFolder, msgs: Array): Array { + fun genUpdateCandidates( + map: Map, + folder: IMAPFolder, + msgs: Array + ): Array { val updateCandidates = mutableListOf() try { for (msg in msgs) { @@ -453,7 +483,11 @@ class EmailUtil { * @return A list of messages which already exist in the local database. * @throws MessagingException for other failures. */ - fun getUpdatedMsgs(folder: IMAPFolder, loadedMsgsCount: Int, newMsgsCount: Int): Array { + fun getUpdatedMsgs( + folder: IMAPFolder, + loadedMsgsCount: Int, + newMsgsCount: Int + ): Array { val end = folder.messageCount - newMsgsCount var start = end - loadedMsgsCount + 1 @@ -512,7 +546,11 @@ class EmailUtil { * @return A list of messages which already exist in the local database. * @throws MessagingException for other failures. */ - fun getUpdatedMsgsByUIDs(folder: IMAPFolder, uids: LongArray, fetchFlags: Boolean = true): Array { + fun getUpdatedMsgsByUIDs( + folder: IMAPFolder, + uids: LongArray, + fetchFlags: Boolean = true + ): Array { return if (uids.isEmpty()) { arrayOf() } else { @@ -633,8 +671,10 @@ class EmailUtil { * an outgoing message. * @return The generated raw MIME message. */ - fun genMessage(context: Context, accountEntity: AccountEntity, - outgoingMsgInfo: OutgoingMessageInfo): Message { + fun genMessage( + context: Context, accountEntity: AccountEntity, + outgoingMsgInfo: OutgoingMessageInfo + ): Message { val session = Session.getInstance(Properties()) val senderEmail = outgoingMsgInfo.from val senderKeyDetails = SecurityUtils.getSenderKeyDetails(context, accountEntity, senderEmail) @@ -645,10 +685,13 @@ class EmailUtil { if (outgoingMsgInfo.encryptionType === MessageEncryptionType.ENCRYPTED) { val recipients = outgoingMsgInfo.getAllRecipients().toMutableList() pubKeys = SecurityUtils.getRecipientsPubKeys(context, recipients) - pubKeys.add(senderKeyDetails.publicKey - ?: throw IllegalStateException("Sender pub key not found")) - prvKeys = listOf(senderKeyDetails.privateKey - ?: throw IllegalStateException("Sender private key not found")) + pubKeys.add( + senderKeyDetails.publicKey + ) + prvKeys = listOf( + senderKeyDetails.privateKey + ?: throw IllegalStateException("Sender private key not found") + ) ringProtector = KeysStorageImpl.getInstance(context).getSecretKeyRingProtector() } @@ -670,13 +713,17 @@ class EmailUtil { * @return The next [UID] value for the outgoing message. */ fun genOutboxUID(context: Context?): Long { - var lastUid = SharedPreferencesHelper.getLong(PreferenceManager.getDefaultSharedPreferences(context), - Constants.PREF_KEY_LAST_OUTBOX_UID, 0) + var lastUid = SharedPreferencesHelper.getLong( + PreferenceManager.getDefaultSharedPreferences(context), + Constants.PREF_KEY_LAST_OUTBOX_UID, 0 + ) lastUid++ - SharedPreferencesHelper.setLong(PreferenceManager.getDefaultSharedPreferences(context), - Constants.PREF_KEY_LAST_OUTBOX_UID, lastUid) + SharedPreferencesHelper.setLong( + PreferenceManager.getDefaultSharedPreferences(context), + Constants.PREF_KEY_LAST_OUTBOX_UID, lastUid + ) return lastUid } @@ -712,12 +759,22 @@ class EmailUtil { private fun getBodyPartWithBackupText(context: Context): BodyPart { val messageBodyPart = MimeBodyPart() - messageBodyPart.setContent(GeneralUtil.removeAllComments(IOUtils.toString(context.assets - .open(HTML_EMAIL_INTRO_TEMPLATE_HTM), StandardCharsets.UTF_8)), JavaEmailConstants.MIME_TYPE_TEXT_HTML) + messageBodyPart.setContent( + GeneralUtil.removeAllComments( + IOUtils.toString( + context.assets + .open(HTML_EMAIL_INTRO_TEMPLATE_HTM), StandardCharsets.UTF_8 + ) + ), JavaEmailConstants.MIME_TYPE_TEXT_HTML + ) return messageBodyPart } - private fun genMsgWithBackupTemplate(context: Context, account: AccountEntity, session: Session): Message { + private fun genMsgWithBackupTemplate( + context: Context, + account: AccountEntity, + session: Session + ): Message { val msg = FlowCryptMimeMessage(session) msg.setFrom(InternetAddress(account.email)) @@ -759,7 +816,12 @@ class EmailUtil { val partsNumber = multiPart.count for (partCount in 0 until partsNumber) { val bodyPart = multiPart.getBodyPart(partCount) - attachmentInfoList.addAll(getAttsInfoFromPart(bodyPart, "$depth${AttachmentInfo.DEPTH_SEPARATOR}$partCount")) + attachmentInfoList.addAll( + getAttsInfoFromPart( + bodyPart, + "$depth${AttachmentInfo.DEPTH_SEPARATOR}$partCount" + ) + ) } } else if (Part.ATTACHMENT.equals(part.disposition, ignoreCase = true)) { val attachmentInfo = AttachmentInfo() @@ -767,7 +829,7 @@ class EmailUtil { attachmentInfo.encodedSize = part.size.toLong() attachmentInfo.type = part.contentType ?: "" attachmentInfo.id = (part as? IMAPBodyPart)?.contentID - ?: generateContentId(AttachmentInfo.INNER_ATTACHMENT_PREFIX) + ?: generateContentId(AttachmentInfo.INNER_ATTACHMENT_PREFIX) attachmentInfo.path = depth attachmentInfoList.add(attachmentInfo) } @@ -821,7 +883,8 @@ class EmailUtil { */ @SuppressLint("SimpleDateFormat") // for now we use iso format, regardles of locality fun genReplyContent(msgInfo: IncomingMessageInfo?): String { - val date = if (msgInfo != null) SimpleDateFormat("yyyy-MM-dd' at 'HH:mm").format(msgInfo.getReceiveDate()) else "unknown date" + val date = + if (msgInfo != null) SimpleDateFormat("yyyy-MM-dd' at 'HH:mm").format(msgInfo.getReceiveDate()) else "unknown date" val sender = msgInfo?.getFrom()?.firstOrNull()?.toString() ?: "unknown sender" val replyText = prepareReplyQuotes(msgInfo?.text) return "\n\nOn $date, $sender wrote:\n$replyText" @@ -882,14 +945,22 @@ class EmailUtil { if (isEncryptedModeEnabled == true) { val searchTerm = genEncryptedMsgsSearchTerm(account) - return if (AccountEntity.ACCOUNT_TYPE_GOOGLE.equals(account.accountType, ignoreCase = true)) { + return if (AccountEntity.ACCOUNT_TYPE_GOOGLE.equals( + account.accountType, + ignoreCase = true + ) + ) { val stringTerm = searchTerm as StringTerm GmailRawSearchTerm(localFolder.searchQuery + " AND (" + stringTerm.pattern + ")") } else { AndTerm(searchTerm, generateNonGmailSearchTerm(localFolder)) } } else { - return if (AccountEntity.ACCOUNT_TYPE_GOOGLE.equals(account.accountType, ignoreCase = true)) { + return if (AccountEntity.ACCOUNT_TYPE_GOOGLE.equals( + account.accountType, + ignoreCase = true + ) + ) { GmailRawSearchTerm(localFolder.searchQuery) } else { generateNonGmailSearchTerm(localFolder) @@ -947,17 +1018,17 @@ class EmailUtil { */ fun getGmailBackupSearchQuery(email: String): String { val subjects = listOf( - "Your FlowCrypt Backup", - "Your CryptUp Backup", - "All you need to know about CryptUP (contains a backup)", - "CryptUP Account Backup" + "Your FlowCrypt Backup", + "Your CryptUp Backup", + "All you need to know about CryptUP (contains a backup)", + "CryptUP Account Backup" ) val parameters = listOf( - "from:${email}", - "to:${email}", - """(subject:"${subjects.joinToString(separator = """" OR subject: """")}")""", - "-is:spam" + "from:${email}", + "to:${email}", + """(subject:"${subjects.joinToString(separator = """" OR subject: """")}")""", + "-is:spam" ) return parameters.joinToString(separator = " ") @@ -971,11 +1042,13 @@ class EmailUtil { } } - fun prepareNewMsg(session: Session, - info: OutgoingMessageInfo, - pubKeys: List? = null, - prvKeys: List? = null, - protector: SecretKeyRingProtector? = null): MimeMessage { + fun prepareNewMsg( + session: Session, + info: OutgoingMessageInfo, + pubKeys: List? = null, + prvKeys: List? = null, + protector: SecretKeyRingProtector? = null + ): MimeMessage { val msg = FlowCryptMimeMessage(session) msg.subject = info.subject msg.setFrom(InternetAddress(info.from)) @@ -990,11 +1063,13 @@ class EmailUtil { return msg } - fun genReplyMessage(replyToMsg: MimeMessage, - info: OutgoingMessageInfo, - pubKeys: List? = null, - prvKeys: List? = null, - protector: SecretKeyRingProtector? = null): Message { + fun genReplyMessage( + replyToMsg: MimeMessage, + info: OutgoingMessageInfo, + pubKeys: List? = null, + prvKeys: List? = null, + protector: SecretKeyRingProtector? = null + ): Message { val reply = replyToMsg.reply(false)//we use replyToAll == false to use the own logic reply.setFrom(InternetAddress(info.from)) reply.setText(prepareMsgContent(info, pubKeys, prvKeys, protector)) @@ -1005,37 +1080,41 @@ class EmailUtil { } private fun generateNonGmailSearchTerm(localFolder: LocalFolder): SearchTerm { - return OrTerm(arrayOf( + return OrTerm( + arrayOf( SubjectTerm(localFolder.searchQuery), BodyTerm(localFolder.searchQuery), FromStringTerm(localFolder.searchQuery), RecipientStringTerm(Message.RecipientType.TO, localFolder.searchQuery), RecipientStringTerm(Message.RecipientType.CC, localFolder.searchQuery), RecipientStringTerm(Message.RecipientType.BCC, localFolder.searchQuery) - )) + ) + ) } private fun prepareReplyMsg( - context: Context, - session: Session, - info: OutgoingMessageInfo, - pubKeys: List?, - prvKeys: List? = null, - protector: SecretKeyRingProtector? = null): Message { + context: Context, + session: Session, + info: OutgoingMessageInfo, + pubKeys: List?, + prvKeys: List? = null, + protector: SecretKeyRingProtector? = null + ): Message { val replyToMessageEntity = info.replyToMsgEntity - ?: throw IllegalArgumentException("Empty replyTo MessageEntity") + ?: throw IllegalArgumentException("Empty replyTo MessageEntity") var msg: MimeMessage if (replyToMessageEntity.rawMessageWithoutAttachments.isNullOrEmpty()) { val snapshot = MsgsCacheManager.getMsgSnapshot(replyToMessageEntity.id.toString()) - ?: throw IllegalArgumentException("Snapshot of replyTo message not found") + ?: throw IllegalArgumentException("Snapshot of replyTo message not found") val uri = snapshot.getUri(0) ?: throw IllegalArgumentException("Uri not found") val input = context.contentResolver?.openInputStream(uri) - ?: throw IllegalArgumentException("InputStream not found") + ?: throw IllegalArgumentException("InputStream not found") msg = FlowCryptMimeMessage(session, KeyStoreCryptoManager.getCipherInputStream(input)) } else { val input = ByteArrayInputStream( - replyToMessageEntity.rawMessageWithoutAttachments.toByteArray()) + replyToMessageEntity.rawMessageWithoutAttachments.toByteArray() + ) try { msg = FlowCryptMimeMessage(session, KeyStoreCryptoManager.getCipherInputStream(input)) } catch (e: Exception) { @@ -1047,15 +1126,18 @@ class EmailUtil { return genReplyMessage(msg, info, pubKeys, prvKeys, protector) } - private fun prepareMsgContent(info: OutgoingMessageInfo, pubKeys: List? = null, - prvKeys: List? = null, - protector: SecretKeyRingProtector? = null): String { + private fun prepareMsgContent( + info: OutgoingMessageInfo, pubKeys: List? = null, + prvKeys: List? = null, + protector: SecretKeyRingProtector? = null + ): String { return if (info.encryptionType == MessageEncryptionType.ENCRYPTED) { PgpEncrypt.encryptAndOrSignMsg( - msg = info.msg ?: "", - pubKeys = pubKeys ?: emptyList(), - prvKeys = prvKeys, - secretKeyRingProtector = protector) + msg = info.msg ?: "", + pubKeys = pubKeys ?: emptyList(), + prvKeys = prvKeys, + secretKeyRingProtector = protector + ) } else { info.msg ?: "" } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/FlowCryptMimeMessage.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/FlowCryptMimeMessage.kt index 1397fab291..d7b9726067 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/FlowCryptMimeMessage.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/FlowCryptMimeMessage.kt @@ -35,4 +35,4 @@ open class FlowCryptMimeMessage : MimeMessage { val modifiedMessageId = originalMessageId.replace("@.*>\$".toRegex(), "@$domain>") setHeader("Message-ID", modifiedMessageId) } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/FoldersManager.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/FoldersManager.kt index a4a455a800..74245f52c8 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/FoldersManager.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/FoldersManager.kt @@ -119,7 +119,10 @@ class FoldersManager constructor(val account: String) { */ fun addFolder(imapFolder: IMAPFolder?) { imapFolder?.let { - if (!EmailUtil.containsNoSelectAttr(it) && !TextUtils.isEmpty(it.fullName) && !folders.containsKey(it.fullName)) { + if (!EmailUtil.containsNoSelectAttr(it) && !TextUtils.isEmpty(it.fullName) && !folders.containsKey( + it.fullName + ) + ) { this.folders[prepareFolderKey(it)] = generateFolder(account, it, imapFolder.name) } } @@ -145,7 +148,10 @@ class FoldersManager constructor(val account: String) { * remote folder. */ fun addFolder(localFolder: LocalFolder?) { - if (localFolder != null && !TextUtils.isEmpty(localFolder.fullName) && !folders.containsKey(localFolder.fullName)) { + if (localFolder != null && !TextUtils.isEmpty(localFolder.fullName) && !folders.containsKey( + localFolder.fullName + ) + ) { this.folders[prepareFolderKey(localFolder)] = localFolder } } @@ -305,7 +311,11 @@ class FoldersManager constructor(val account: String) { @WorkerThread fun fromDatabase(context: Context, accountEntity: AccountEntity): FoldersManager { val appContext = context.applicationContext - return build(accountEntity.email, FlowCryptRoomDatabase.getDatabase(appContext).labelDao().getLabels(accountEntity.email, accountEntity.accountType)) + return build( + accountEntity.email, + FlowCryptRoomDatabase.getDatabase(appContext).labelDao() + .getLabels(accountEntity.email, accountEntity.accountType) + ) } /** @@ -317,10 +327,15 @@ class FoldersManager constructor(val account: String) { * @return The new [FoldersManager]. */ @WorkerThread - suspend fun fromDatabaseSuspend(context: Context, accountEntity: AccountEntity): FoldersManager { + suspend fun fromDatabaseSuspend( + context: Context, + accountEntity: AccountEntity + ): FoldersManager { val appContext = context.applicationContext - return build(accountEntity.email, FlowCryptRoomDatabase.getDatabase(appContext).labelDao() - .getLabelsSuspend(accountEntity.email, accountEntity.accountType)) + return build( + accountEntity.email, FlowCryptRoomDatabase.getDatabase(appContext).labelDao() + .getLabelsSuspend(accountEntity.email, accountEntity.accountType) + ) } /** @@ -333,8 +348,12 @@ class FoldersManager constructor(val account: String) { * @throws MessagingException */ fun generateFolder(account: String, imapFolder: IMAPFolder, folderAlias: String?): LocalFolder { - return LocalFolder(account, imapFolder.fullName, folderAlias, Arrays.asList(*imapFolder - .attributes), isCustom(imapFolder), 0, "") + return LocalFolder( + account, imapFolder.fullName, folderAlias, Arrays.asList( + *imapFolder + .attributes + ), isCustom(imapFolder), 0, "" + ) } /** @@ -344,7 +363,15 @@ class FoldersManager constructor(val account: String) { * @param folderAlias The folder alias. */ fun generateFolder(account: String, label: Label): LocalFolder { - return LocalFolder(account, label.id, label.name, emptyList(), label.type == GmailApiHelper.FOLDER_TYPE_USER, 0, "") + return LocalFolder( + account, + label.id, + label.name, + emptyList(), + label.type == GmailApiHelper.FOLDER_TYPE_USER, + 0, + "" + ) } /** @@ -389,14 +416,38 @@ class FoldersManager constructor(val account: String) { } return when { - JavaEmailConstants.FOLDER_INBOX.equals(localFolder?.fullName, ignoreCase = true) -> FolderType.INBOX - JavaEmailConstants.FOLDER_OUTBOX.equals(localFolder?.fullName, ignoreCase = true) -> FolderType.OUTBOX - JavaEmailConstants.FOLDER_SENT.equals(localFolder?.fullName, ignoreCase = true) -> FolderType.SENT - JavaEmailConstants.FOLDER_TRASH.equals(localFolder?.fullName, ignoreCase = true) -> FolderType.TRASH - JavaEmailConstants.FOLDER_DRAFT.equals(localFolder?.fullName, ignoreCase = true) -> FolderType.DRAFTS - JavaEmailConstants.FOLDER_STARRED.equals(localFolder?.fullName, ignoreCase = true) -> FolderType.STARRED - JavaEmailConstants.FOLDER_IMPORTANT.equals(localFolder?.fullName, ignoreCase = true) -> FolderType.IMPORTANT - JavaEmailConstants.FOLDER_SPAM.equals(localFolder?.fullName, ignoreCase = true) -> FolderType.SPAM + JavaEmailConstants.FOLDER_INBOX.equals( + localFolder?.fullName, + ignoreCase = true + ) -> FolderType.INBOX + JavaEmailConstants.FOLDER_OUTBOX.equals( + localFolder?.fullName, + ignoreCase = true + ) -> FolderType.OUTBOX + JavaEmailConstants.FOLDER_SENT.equals( + localFolder?.fullName, + ignoreCase = true + ) -> FolderType.SENT + JavaEmailConstants.FOLDER_TRASH.equals( + localFolder?.fullName, + ignoreCase = true + ) -> FolderType.TRASH + JavaEmailConstants.FOLDER_DRAFT.equals( + localFolder?.fullName, + ignoreCase = true + ) -> FolderType.DRAFTS + JavaEmailConstants.FOLDER_STARRED.equals( + localFolder?.fullName, + ignoreCase = true + ) -> FolderType.STARRED + JavaEmailConstants.FOLDER_IMPORTANT.equals( + localFolder?.fullName, + ignoreCase = true + ) -> FolderType.IMPORTANT + JavaEmailConstants.FOLDER_SPAM.equals( + localFolder?.fullName, + ignoreCase = true + ) -> FolderType.SPAM else -> null } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/IMAPStoreConnection.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/IMAPStoreConnection.kt index 1c283a50e1..01d2a7baa0 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/IMAPStoreConnection.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/IMAPStoreConnection.kt @@ -32,7 +32,10 @@ import javax.net.ssl.SSLProtocolException * Time: 11:30 AM * E-mail: DenBond7@gmail.com */ -class IMAPStoreConnection(override val context: Context, override val accountEntity: AccountEntity) : StoreConnection { +class IMAPStoreConnection( + override val context: Context, + override val accountEntity: AccountEntity +) : StoreConnection { override val session = OpenStoreHelper.getAccountSess(context, accountEntity) @Volatile @@ -45,46 +48,84 @@ class IMAPStoreConnection(override val context: Context, override val accountEnt override suspend fun connect() = withContext(Dispatchers.IO) { mutex.withLock { - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "connect(${accountEntity.email}): check connection") + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "connect(${accountEntity.email}): check connection" + ) if (isConnected()) { - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "connect(${accountEntity.email}): connected, skip connection") + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "connect(${accountEntity.email}): connected, skip connection" + ) return@withContext } try { - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "connect(${accountEntity.email}): try to open a new connection to store") + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "connect(${accountEntity.email}): try to open a new connection to store" + ) OpenStoreHelper.openStore(context, accountEntity, store) - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "connect(${accountEntity.email}): connected to store") + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "connect(${accountEntity.email}): connected to store" + ) } catch (e: Throwable) { - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "connect(${accountEntity.email}): connection to store failed", e) + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "connect(${accountEntity.email}): connection to store failed", + e + ) throw e } } } override suspend fun reconnect() = withContext(Dispatchers.IO) { - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "reconnect(${accountEntity.email}): begin reconnection") + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "reconnect(${accountEntity.email}): begin reconnection" + ) disconnect() connect() - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "reconnect(${accountEntity.email}): reconnection completed") + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "reconnect(${accountEntity.email}): reconnection completed" + ) } override suspend fun disconnect() = withContext(Dispatchers.IO) { mutex.withLock { - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "disconnect(${accountEntity.email}): check connection") + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "disconnect(${accountEntity.email}): check connection" + ) if (!isConnected()) { - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "disconnect(${accountEntity.email}): disconnected, skipping...") + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "disconnect(${accountEntity.email}): disconnected, skipping..." + ) return@withContext } try { - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "disconnect(${accountEntity.email}): disconnecting...") + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "disconnect(${accountEntity.email}): disconnecting..." + ) if (store.isConnected) { store.close() } - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "disconnect(${accountEntity.email}): disconnected") + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "disconnect(${accountEntity.email}): disconnected" + ) } catch (e: Throwable) { - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "disconnect(${accountEntity.email}): disconnecting failed", e) + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "disconnect(${accountEntity.email}): disconnecting failed", + e + ) throw e } } @@ -94,53 +135,69 @@ class IMAPStoreConnection(override val context: Context, override val accountEnt return@withContext store.isConnected } - override suspend fun execute(action: suspend (store: Store) -> T): T = withContext(Dispatchers.IO) { - return@withContext try { - if (!isConnected()) { - connect() - } + override suspend fun execute(action: suspend (store: Store) -> T): T = + withContext(Dispatchers.IO) { + return@withContext try { + if (!isConnected()) { + connect() + } - action.invoke(store) - } catch (e: Exception) { - throw processException(e) + action.invoke(store) + } catch (e: Exception) { + throw processException(e) + } } - } - override suspend fun executeWithResult(action: suspend (store: Store) -> Result): Result = withContext(Dispatchers.IO) { - return@withContext try { - if (!isConnected()) { - connect() - } + override suspend fun executeWithResult(action: suspend (store: Store) -> Result): Result = + withContext(Dispatchers.IO) { + return@withContext try { + if (!isConnected()) { + connect() + } - action.invoke(store) - } catch (e: Exception) { - when (val exception = processException(e)) { - is CommonConnectionException -> Result.exception(exception) + action.invoke(store) + } catch (e: Exception) { + when (val exception = processException(e)) { + is CommonConnectionException -> Result.exception(exception) - else -> { - ExceptionUtil.handleError(exception) - Result.exception(exception) + else -> { + ExceptionUtil.handleError(exception) + Result.exception(exception) + } } } } - } - override suspend fun executeIMAPAction(action: suspend (store: Store) -> Unit) = withContext(Dispatchers.IO) { - try { - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "executeIMAPAction(${accountEntity.email}): start ${action.javaClass}") - if (!isConnected()) { - connect() - } + override suspend fun executeIMAPAction(action: suspend (store: Store) -> Unit) = + withContext(Dispatchers.IO) { + try { + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "executeIMAPAction(${accountEntity.email}): start ${action.javaClass}" + ) + if (!isConnected()) { + connect() + } - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "executeIMAPAction(${accountEntity.email}): start invoke ${action.javaClass}") - action.invoke(store) - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "executeIMAPAction(${accountEntity.email}): invoke ${action.javaClass} completed") - } catch (e: Exception) { - LogsUtil.d(IMAPStoreConnection::class.java.simpleName, "executeIMAPAction(${accountEntity.email}): invoke ${action.javaClass} failed", e) - val exception = processException(e) - throw exception + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "executeIMAPAction(${accountEntity.email}): start invoke ${action.javaClass}" + ) + action.invoke(store) + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "executeIMAPAction(${accountEntity.email}): invoke ${action.javaClass} completed" + ) + } catch (e: Exception) { + LogsUtil.d( + IMAPStoreConnection::class.java.simpleName, + "executeIMAPAction(${accountEntity.email}): invoke ${action.javaClass} failed", + e + ) + val exception = processException(e) + throw exception + } } - } private fun processException(e: Throwable): Throwable { return when (e) { @@ -176,4 +233,4 @@ class IMAPStoreConnection(override val context: Context, override val accountEnt || it.contains("connection failure") || it.contains("Error reading input stream") || it.contains("Connection reset;")) -} \ No newline at end of file +} diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/IMAPStoreManager.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/IMAPStoreManager.kt index a6e98ad9d9..7579f19ec3 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/IMAPStoreManager.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/IMAPStoreManager.kt @@ -30,12 +30,14 @@ object IMAPStoreManager { val applicationContext = context.applicationContext val roomDatabase = FlowCryptRoomDatabase.getDatabase(applicationContext) - val pureActiveAccountLiveData: LiveData = roomDatabase.accountDao().getActiveAccountLD() - val activeAccountLiveData: LiveData = pureActiveAccountLiveData.switchMap { accountEntity -> - liveData { - emit(AccountViewModel.getAccountEntityWithDecryptedInfoSuspend(accountEntity)) + val pureActiveAccountLiveData: LiveData = + roomDatabase.accountDao().getActiveAccountLD() + val activeAccountLiveData: LiveData = + pureActiveAccountLiveData.switchMap { accountEntity -> + liveData { + emit(AccountViewModel.getAccountEntityWithDecryptedInfoSuspend(accountEntity)) + } } - } activeAccountLiveData.observeForever { activeAccount -> GlobalScope.launch(Dispatchers.IO) { @@ -77,4 +79,4 @@ object IMAPStoreManager { } } } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/JavaEmailConstants.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/JavaEmailConstants.kt index e3d29c0af4..fea2b01c99 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/JavaEmailConstants.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/JavaEmailConstants.kt @@ -22,7 +22,8 @@ class JavaEmailConstants { /*IMAP*/ const val PROPERTY_NAME_MAIL_IMAP_SSL_ENABLE = "mail.imap.ssl.enable" - const val PROPERTY_NAME_MAIL_IMAP_SSL_CHECK_SERVER_IDENTITY = "mail.imap.ssl.checkserveridentity" + const val PROPERTY_NAME_MAIL_IMAP_SSL_CHECK_SERVER_IDENTITY = + "mail.imap.ssl.checkserveridentity" const val PROPERTY_NAME_MAIL_IMAP_STARTTLS_ENABLE = "mail.imap.starttls.enable" const val PROPERTY_NAME_MAIL_IMAP_AUTH_MECHANISMS = "mail.imap.auth.mechanisms" const val PROPERTY_NAME_MAIL_IMAP_FETCH_SIZE = "mail.imap.fetchsize" @@ -41,7 +42,8 @@ class JavaEmailConstants { /*SMTP*/ const val PROPERTY_NAME_MAIL_SMTP_AUTH = "mail.smtp.auth" const val PROPERTY_NAME_MAIL_SMTP_SSL_ENABLE = "mail.smtp.ssl.enable" - const val PROPERTY_NAME_MAIL_SMTP_SSL_CHECK_SERVER_IDENTITY = "mail.smtp.ssl.checkserveridentity" + const val PROPERTY_NAME_MAIL_SMTP_SSL_CHECK_SERVER_IDENTITY = + "mail.smtp.ssl.checkserveridentity" const val PROPERTY_NAME_MAIL_SMTP_STARTTLS_ENABLE = "mail.smtp.starttls.enable" const val PROPERTY_NAME_MAIL_SMTP_AUTH_MECHANISMS = "mail.smtp.auth.mechanisms" const val PROPERTY_NAME_MAIL_SMTP_CONNECTIONTIMEOUT = "mail.smtp.connectiontimeout" diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/MsgsCacheManager.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/MsgsCacheManager.kt index 6c8b5e727e..04f0f5c9d4 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/MsgsCacheManager.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/MsgsCacheManager.kt @@ -37,7 +37,12 @@ object MsgsCacheManager { lateinit var diskLruCache: DiskLruCache fun init(context: Context) { - diskLruCache = DiskLruCache(FileSystem.SYSTEM, File(context.filesDir, CACHE_DIR_NAME), CACHE_VERSION, CACHE_SIZE) + diskLruCache = DiskLruCache( + FileSystem.SYSTEM, + File(context.filesDir, CACHE_DIR_NAME), + CACHE_VERSION, + CACHE_SIZE + ) } fun storeMsg(key: String, msg: MimeMessage) { @@ -81,11 +86,17 @@ object MsgsCacheManager { val bufferedSink = editor.newSink().buffer() val outputStreamOfBufferedSink = ProgressOutputStream(bufferedSink.outputStream()) val cipherForEncryption = KeyStoreCryptoManager.getCipherForEncryption() - val base64OutputStream = Base64OutputStream(outputStreamOfBufferedSink, KeyStoreCryptoManager.BASE64_FLAGS) + val base64OutputStream = + Base64OutputStream(outputStreamOfBufferedSink, KeyStoreCryptoManager.BASE64_FLAGS) val outputStream = CipherOutputStream(base64OutputStream, cipherForEncryption) outputStream.use { - outputStreamOfBufferedSink.write(Base64.encodeToString(cipherForEncryption.iv, KeyStoreCryptoManager.BASE64_FLAGS).toByteArray()) + outputStreamOfBufferedSink.write( + Base64.encodeToString( + cipherForEncryption.iv, + KeyStoreCryptoManager.BASE64_FLAGS + ).toByteArray() + ) outputStreamOfBufferedSink.write("\n".toByteArray()) action.invoke(outputStream) bufferedSink.flush() @@ -98,4 +109,4 @@ object MsgsCacheManager { throw e } } -} \ No newline at end of file +} diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/SearchBackupsUtil.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/SearchBackupsUtil.kt index c8d51cdbf7..598ad05560 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/SearchBackupsUtil.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/SearchBackupsUtil.kt @@ -31,16 +31,22 @@ class SearchBackupsUtil { * @return Generated [SearchTerm]. */ fun genSearchTerms(email: String): SearchTerm { - val subjectTerms = OrTerm(arrayOf( + val subjectTerms = OrTerm( + arrayOf( SubjectTerm("Your CryptUp Backup"), SubjectTerm("Your FlowCrypt Backup"), SubjectTerm("Your CryptUP Backup"), SubjectTerm("All you need to know about CryptUP (contains a backup)"), - SubjectTerm("CryptUP Account Backup"))) - return AndTerm(arrayOf( + SubjectTerm("CryptUP Account Backup") + ) + ) + return AndTerm( + arrayOf( subjectTerms, FromTerm(InternetAddress(email)), - RecipientTerm(Message.RecipientType.TO, InternetAddress(email)))) + RecipientTerm(Message.RecipientType.TO, InternetAddress(email)) + ) + ) } } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/StoreConnection.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/StoreConnection.kt index a08bceaec3..0d915fb349 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/StoreConnection.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/StoreConnection.kt @@ -49,4 +49,4 @@ interface StoreConnection { @WorkerThread suspend fun executeIMAPAction(action: suspend (store: Store) -> Unit) -} \ No newline at end of file +} diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/gmail/GmailApiHelper.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/gmail/GmailApiHelper.kt index 9ce336eec3..791ee97342 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/gmail/GmailApiHelper.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/gmail/GmailApiHelper.kt @@ -86,7 +86,8 @@ import javax.net.ssl.SSLException class GmailApiHelper { companion object { const val DEFAULT_USER_ID = "me" - const val PATTERN_SEARCH_ENCRYPTED_MESSAGES = "PGP OR GPG OR OpenPGP OR filename:asc OR filename:message OR filename:pgp OR filename:gpg" + const val PATTERN_SEARCH_ENCRYPTED_MESSAGES = + "PGP OR GPG OR OpenPGP OR filename:asc OR filename:message OR filename:pgp OR filename:gpg" const val MESSAGE_RESPONSE_FORMAT_RAW = "raw" const val MESSAGE_RESPONSE_FORMAT_FULL = "full" @@ -101,45 +102,48 @@ class GmailApiHelper { private val SCOPES = arrayOf(GmailScopes.MAIL_GOOGLE_COM) private val HIDDEN_LABEL_IDS = arrayOf( - "CHAT", - "CATEGORY_FORUMS", - "CATEGORY_UPDATES", - "CATEGORY_PERSONAL", - "CATEGORY_PROMOTIONS", - "CATEGORY_SOCIAL") - private const val COUNT_OF_LOADED_EMAILS_BY_STEP = JavaEmailConstants.COUNT_OF_LOADED_EMAILS_BY_STEP.toLong() + "CHAT", + "CATEGORY_FORUMS", + "CATEGORY_UPDATES", + "CATEGORY_PERSONAL", + "CATEGORY_PROMOTIONS", + "CATEGORY_SOCIAL" + ) + private const val COUNT_OF_LOADED_EMAILS_BY_STEP = + JavaEmailConstants.COUNT_OF_LOADED_EMAILS_BY_STEP.toLong() private val FULL_INFO_WITHOUT_DATA = listOf( - "id", - "threadId", - "labelIds", - "snippet", - "sizeEstimate", - "historyId", - "internalDate", - "payload/partId", - "payload/mimeType", - "payload/filename", - "payload/headers", - "payload/body", - "payload/parts(partId,mimeType,filename,headers,body/size,body/attachmentId)" + "id", + "threadId", + "labelIds", + "snippet", + "sizeEstimate", + "historyId", + "internalDate", + "payload/partId", + "payload/mimeType", + "payload/filename", + "payload/headers", + "payload/body", + "payload/parts(partId,mimeType,filename,headers,body/size,body/attachmentId)" ) - suspend fun executeWithResult(action: suspend () -> Result): Result = withContext(Dispatchers.IO) { - return@withContext try { - action.invoke() - } catch (e: Exception) { - e.printStackTrace() - when (val exception = processException(e)) { - is CommonConnectionException -> Result.exception(exception) - - else -> { - ExceptionUtil.handleError(exception) - Result.exception(exception) + suspend fun executeWithResult(action: suspend () -> Result): Result = + withContext(Dispatchers.IO) { + return@withContext try { + action.invoke() + } catch (e: Exception) { + e.printStackTrace() + when (val exception = processException(e)) { + is CommonConnectionException -> Result.exception(exception) + + else -> { + ExceptionUtil.handleError(exception) + Result.exception(exception) + } } } } - } /** * Generate [Gmail] using incoming [AccountEntity]. [Gmail] class is the main point of @@ -172,8 +176,10 @@ class GmailApiHelper { return Gmail.Builder(transport, factory, credential).setApplicationName(appName).build() } - suspend fun doOperationViaStepsSuspend(stepValue: Int = 50, list: List, - block: suspend (list: List) -> List): List = withContext(Dispatchers.IO) { + suspend fun doOperationViaStepsSuspend( + stepValue: Int = 50, list: List, + block: suspend (list: List) -> List + ): List = withContext(Dispatchers.IO) { val resultList = mutableListOf() if (list.isNotEmpty()) { if (list.size <= stepValue) { @@ -195,36 +201,43 @@ class GmailApiHelper { return@withContext resultList } - suspend fun getWholeMimeMessageInputStream(context: Context, account: AccountEntity?, messageEntity: MessageEntity): InputStream = withContext(Dispatchers.IO) { + suspend fun getWholeMimeMessageInputStream( + context: Context, + account: AccountEntity?, + messageEntity: MessageEntity + ): InputStream = withContext(Dispatchers.IO) { val msgId = messageEntity.uidAsHEX val gmailApiService = generateGmailApiService(context, account) val message = gmailApiService - .users() - .messages() - .get(DEFAULT_USER_ID, msgId) - .setFormat(MESSAGE_RESPONSE_FORMAT_RAW) + .users() + .messages() + .get(DEFAULT_USER_ID, msgId) + .setFormat(MESSAGE_RESPONSE_FORMAT_RAW) message.fields = "raw" return@withContext Base64InputStream(GMailRawMIMEMessageFilterInputStream(message.executeAsInputStream())) } - suspend fun loadMsgsBaseInfo(context: Context, accountEntity: AccountEntity, localFolder: - LocalFolder, nextPageToken: String? = null): ListMessagesResponse = withContext(Dispatchers.IO) { + suspend fun loadMsgsBaseInfo( + context: Context, accountEntity: AccountEntity, localFolder: + LocalFolder, nextPageToken: String? = null + ): ListMessagesResponse = withContext(Dispatchers.IO) { val gmailApiService = generateGmailApiService(context, accountEntity) val request = gmailApiService - .users() - .messages() - .list(DEFAULT_USER_ID) - .setPageToken(nextPageToken) - .setMaxResults(COUNT_OF_LOADED_EMAILS_BY_STEP) + .users() + .messages() + .list(DEFAULT_USER_ID) + .setPageToken(nextPageToken) + .setMaxResults(COUNT_OF_LOADED_EMAILS_BY_STEP) if (!localFolder.isAll()) { request.labelIds = listOf(localFolder.fullName) } if (accountEntity.isShowOnlyEncrypted == true) { - request.q = (EmailUtil.genEncryptedMsgsSearchTerm(accountEntity) as? GmailRawSearchTerm)?.pattern + request.q = + (EmailUtil.genEncryptedMsgsSearchTerm(accountEntity) as? GmailRawSearchTerm)?.pattern } return@withContext request.execute() @@ -234,9 +247,11 @@ class GmailApiHelper { * This method is responsible for loading messages. If the input list of Message large than the * twice value of stepValue we will use parallel requests to minimize latency */ - suspend fun loadMsgsInParallel(context: Context, accountEntity: AccountEntity, messages: List, - localFolder: LocalFolder, - format: String = MESSAGE_RESPONSE_FORMAT_FULL, stepValue: Int = 10): List = withContext(Dispatchers.IO) + suspend fun loadMsgsInParallel( + context: Context, accountEntity: AccountEntity, messages: List, + localFolder: LocalFolder, + format: String = MESSAGE_RESPONSE_FORMAT_FULL, stepValue: Int = 10 + ): List = withContext(Dispatchers.IO) { val useParallel = messages.size > stepValue * 2 val steps = mutableListOf>>() @@ -263,9 +278,10 @@ class GmailApiHelper { return@withContext awaitAll(*steps.toTypedArray()).flatten() } - suspend fun loadMsgs(context: Context, accountEntity: AccountEntity, messages: Collection, - localFolder: LocalFolder, format: String = MESSAGE_RESPONSE_FORMAT_FULL, - metadataHeaders: List? = null, fields: List? = FULL_INFO_WITHOUT_DATA + suspend fun loadMsgs( + context: Context, accountEntity: AccountEntity, messages: Collection, + localFolder: LocalFolder, format: String = MESSAGE_RESPONSE_FORMAT_FULL, + metadataHeaders: List? = null, fields: List? = FULL_INFO_WITHOUT_DATA ): List = withContext(Dispatchers.IO) { val gmailApiService = generateGmailApiService(context, accountEntity) @@ -276,10 +292,10 @@ class GmailApiHelper { for (message in messages) { val request = gmailApiService - .users() - .messages() - .get(DEFAULT_USER_ID, message.id) - .setFormat(format) + .users() + .messages() + .get(DEFAULT_USER_ID, message.id) + .setFormat(format) metadataHeaders?.let { metadataHeaders -> request.metadataHeaders = metadataHeaders @@ -309,115 +325,123 @@ class GmailApiHelper { return@withContext listResult } - suspend fun getLabels(context: Context, account: AccountEntity?): List