Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com
* Contributors: DenBond7
*/

package com.flowcrypt.email.ui

import android.view.KeyEvent
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.clearText
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.pressImeActionButton
import androidx.test.espresso.action.ViewActions.pressKey
import androidx.test.espresso.action.ViewActions.replaceText
import androidx.test.espresso.action.ViewActions.typeText
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.flowcrypt.email.R
import com.flowcrypt.email.TestConstants
import com.flowcrypt.email.database.entity.KeyEntity
import com.flowcrypt.email.junit.annotations.FlowCryptTestSettings
import com.flowcrypt.email.rules.AddPrivateKeyToDatabaseRule
import com.flowcrypt.email.rules.ClearAppSettingsRule
import com.flowcrypt.email.rules.GrantPermissionRuleChooser
import com.flowcrypt.email.rules.RetryRule
import com.flowcrypt.email.rules.ScreenshotTestRule
import com.flowcrypt.email.ui.base.BaseComposeScreenNoKeyAvailableTest
import org.junit.Rule
import org.junit.Test
import org.junit.rules.RuleChain
import org.junit.rules.TestRule
import org.junit.runner.RunWith

/**
* @author Denys Bondarenko
*/
@MediumTest
@RunWith(AndroidJUnit4::class)
@FlowCryptTestSettings(useCommonIdling = false)
class ComposeScreenNoKeyAvailableCreateNewKeyFlowTest : BaseComposeScreenNoKeyAvailableTest() {
private val addPrivateKeyToDatabaseRule = AddPrivateKeyToDatabaseRule(
keyPath = "pgp/key_testing@flowcrypt.test_keyA_strong.asc",
passphraseType = KeyEntity.PassphraseType.RAM
)

@get:Rule
var ruleChain: TestRule = RuleChain
.outerRule(RetryRule.DEFAULT)
.around(ClearAppSettingsRule())
.around(GrantPermissionRuleChooser.grant(android.Manifest.permission.POST_NOTIFICATIONS))
.around(addAccountToDatabaseRule)
.around(addPrivateKeyToDatabaseRule)
.around(activeActivityRule)
.around(ScreenshotTestRule())

@Test
fun testCreatingNewKey() {
doBaseActions {
onView(withText(R.string.create_a_new_key))
.check(matches(isDisplayed()))
.perform(click())

Thread.sleep(1000)

onView(withId(R.id.editTextKeyPassword))
.perform(click(), typeText(TestConstants.DEFAULT_STRONG_PASSWORD))
Thread.sleep(1000)
onView(withId(R.id.editTextKeyPassword))
.perform(pressImeActionButton())

Thread.sleep(1000)

onView(withId(R.id.editTextKeyPasswordSecond))
.perform(replaceText(TestConstants.DEFAULT_STRONG_PASSWORD))
onView(withId(R.id.buttonConfirmPassPhrases))
.perform(click())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@ import androidx.test.espresso.action.ViewActions.closeSoftKeyboard
import androidx.test.espresso.action.ViewActions.replaceText
import androidx.test.espresso.action.ViewActions.scrollTo
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.hasTextColor
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.flowcrypt.email.R
import com.flowcrypt.email.TestConstants
import com.flowcrypt.email.extensions.kotlin.asInternetAddress
import com.flowcrypt.email.junit.annotations.FlowCryptTestSettings
import com.flowcrypt.email.rules.AddPrivateKeyToDatabaseRule
import com.flowcrypt.email.rules.ClearAppSettingsRule
Expand All @@ -28,7 +26,6 @@ import com.flowcrypt.email.rules.RetryRule
import com.flowcrypt.email.rules.ScreenshotTestRule
import com.flowcrypt.email.ui.base.BaseComposeScreenNoKeyAvailableTest
import com.flowcrypt.email.util.PrivateKeysManager
import org.hamcrest.CoreMatchers.not
import org.junit.Rule
import org.junit.Test
import org.junit.rules.RuleChain
Expand Down Expand Up @@ -61,52 +58,26 @@ class ComposeScreenNoKeyAvailableSingleKeyWithPassphraseInDatabaseFlowTest : Bas

@Test
fun testImportKey() {
activeActivityRule?.launch(intent)
registerAllIdlingResources()
fillInAllFields(
to = setOf(
requireNotNull(TestConstants.RECIPIENT_WITH_PUBLIC_KEY_ON_ATTESTER.asInternetAddress())
)
)
doBaseActions {
addTextToClipboard("private key", requireNotNull(pgpKeyDetails.privateKey))
onView(withText(R.string.import_private_key))
.check(matches(isDisplayed()))
.perform(click())
Thread.sleep(1000)
onView(withText(R.string.load_from_clipboard))
.check(matches(isDisplayed()))
.perform(click())

//check that editTextFrom has gray text color. It means a sender doesn't have a private key
onView(withId(R.id.editTextFrom))
.check(matches(isDisplayed()))
.check(matches(hasTextColor(R.color.gray)))
onView(withId(R.id.editTextKeyPassword))
.perform(
replaceText(TestConstants.DEFAULT_STRONG_PASSWORD),
closeSoftKeyboard()
)
onView(withId(R.id.buttonPositiveAction))
.perform(scrollTo(), click())

onView(withId(R.id.menuActionSend))
.check(matches(isDisplayed()))
.perform(click())

isDialogWithTextDisplayed(
decorView,
getResString(R.string.no_key_available, addAccountToDatabaseRule.account.email)
)

addTextToClipboard("private key", requireNotNull(pgpKeyDetails.privateKey))
onView(withText(R.string.import_private_key))
.check(matches(isDisplayed()))
.perform(click())

Thread.sleep(1000)
onView(withText(R.string.load_from_clipboard))
.check(matches(isDisplayed()))
.perform(click())

onView(withId(R.id.editTextKeyPassword))
.perform(
replaceText(TestConstants.DEFAULT_STRONG_PASSWORD),
closeSoftKeyboard()
)
onView(withId(R.id.buttonPositiveAction))
.perform(scrollTo(), click())

waitForObjectWithText(addAccountToDatabaseRule.account.email, 5000)

//check that editTextFrom doesn't have gray text color. It means a sender has a private key.
onView(withId(R.id.editTextFrom))
.check(matches(isDisplayed()))
.check(matches(not(hasTextColor(R.color.gray))))
waitForObjectWithText(addAccountToDatabaseRule.account.email, 5000)
}
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ import java.net.HttpURLConnection
abstract class BaseComposeScreenNoKeyAvailableTest : BaseComposeScreenTest() {

protected fun doTestAddEmailToExistingKey(action: () -> Unit) {
doBaseActions {
onView(withText(R.string.add_email_to_existing_key))
.check(matches(isDisplayed()))
.perform(click())

action.invoke()
}
}

protected fun doBaseActions(action: () -> Unit) {
activeActivityRule?.launch(intent)
registerAllIdlingResources()
fillInAllFields(
Expand All @@ -52,13 +62,9 @@ abstract class BaseComposeScreenNoKeyAvailableTest : BaseComposeScreenTest() {
getResString(R.string.no_key_available, addAccountToDatabaseRule.account.email)
)

onView(withText(R.string.add_email_to_existing_key))
.check(matches(isDisplayed()))
.perform(click())

action.invoke()

Thread.sleep(2000)
waitForObjectWithText(getResString(R.string.compose), 5000)

//check that editTextFrom doesn't have gray text color. It means a sender has a private key.
onView(withId(R.id.editTextFrom))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import okhttp3.mockwebserver.Dispatcher
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.RecordedRequest
import org.junit.Assert.assertEquals
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.rules.RuleChain
Expand All @@ -48,6 +49,7 @@ import org.junit.runner.RunWith
message = BaseComposeScreenTest.MESSAGE,
subject = BaseComposeScreenTest.SUBJECT
)
@Ignore("Should be fixed before the next release")
class EncryptedWithAttachmentsComposeGmailApiFlow : BaseComposeGmailFlow() {
override val mockWebServerRule =
FlowCryptMockWebServerRule(TestConstants.MOCK_WEB_SERVER_PORT, object : Dispatcher() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ fun LifecycleOwner.showActionDialogFragment(
requestKey: String,
dialogTitle: String? = null,
isCancelable: Boolean = true,
items: List<DialogItem>
items: List<DialogItem>,
bundle: Bundle? = null
) {
showDialogFragment(navController) {
return@showDialogFragment object : NavDirections {
Expand All @@ -177,7 +178,8 @@ fun LifecycleOwner.showActionDialogFragment(
requestKey = requestKey,
dialogTitle = dialogTitle,
isCancelable = isCancelable,
items = items.toTypedArray()
items = items.toTypedArray(),
bundle = bundle
).toBundle()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import android.view.MenuInflater
import android.view.MenuItem
import android.view.ViewGroup
import android.view.WindowManager
import androidx.activity.OnBackPressedCallback
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
Expand Down Expand Up @@ -51,6 +52,8 @@ abstract class BaseActivity<T : ViewBinding> : AppCompatActivity() {
protected abstract fun inflateBinding(inflater: LayoutInflater): T
protected abstract fun initAppBarConfiguration(): AppBarConfiguration

protected abstract val onBackPressedCallback: OnBackPressedCallback?

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//https://github.com/FlowCrypt/flowcrypt-android/issues/2442
Expand Down Expand Up @@ -83,6 +86,8 @@ abstract class BaseActivity<T : ViewBinding> : AppCompatActivity() {
}
})

onBackPressedCallback?.let { onBackPressedDispatcher.addCallback(this, it) }

initViews()
setupNavigation()
initAccountViewModel()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.navigation.NavHostController
import androidx.navigation.ui.AppBarConfiguration
import com.flowcrypt.email.R
Expand Down Expand Up @@ -48,6 +49,21 @@ class CreateMessageActivity : BaseActivity<ActivityCreateMessageBinding>(),
})
}

override val onBackPressedCallback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (navController.currentDestination?.id == R.id.createMessageFragment) {
onBackPressed()
} else {
navController.navigateUp()
}
}

private fun onBackPressed() {
isEnabled = false
onBackPressedDispatcher.onBackPressed()
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
(navController as? NavHostController)?.enableOnBackPressed(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onServiceDisconnected(arg0: ComponentName) {}
}

private val onBackPressedCallback = object : OnBackPressedCallback(true) {
override val onBackPressedCallback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
binding.drawerLayout.closeDrawer(GravityCompat.START)
Expand Down Expand Up @@ -153,7 +153,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
}
}
super.onCreate(savedInstanceState)
handleOnBackPressed()
observeMovingToBackground()

client = GoogleSignIn.getClient(this, GoogleApiClientHelper.generateGoogleSignInOptions())
Expand Down Expand Up @@ -438,10 +437,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
fragment?.onDrawerStateChanged(slideOffset, isOpened)
}

private fun handleOnBackPressed() {
onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
}

private fun observeMovingToBackground() {
ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver {
/**
Expand Down
Loading