From d472e30b4e52c803d8ef73850674f3652b36aded Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 20 Jun 2015 20:04:33 +0200 Subject: [PATCH] instrument: update symmetric tests --- OpenKeychain/build.gradle | 1 + .../EncryptDecryptSymmetricTests.java | 100 ++++++++++++++---- .../keychain/matcher/CustomMatchers.java | 80 ++++++++++++++ .../keychain/ui/DecryptListFragment.java | 1 + .../keychain/ui/util/KeyFormattingUtils.java | 4 +- .../layout/decrypt_files_list_fragment.xml | 1 - 6 files changed, 162 insertions(+), 25 deletions(-) diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index e2d1dd8c8..45ae01166 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -24,6 +24,7 @@ dependencies { androidTestCompile 'com.android.support.test:runner:0.3' androidTestCompile 'com.android.support.test:rules:0.3' androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2' + androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2' androidTestCompile ('com.android.support.test.espresso:espresso-contrib:2.2') { exclude group: 'com.android.support', module: 'appcompat' exclude group: 'com.android.support', module: 'support-v4' diff --git a/OpenKeychain/src/androidTest/java/org/sufficientlysecure/keychain/EncryptDecryptSymmetricTests.java b/OpenKeychain/src/androidTest/java/org/sufficientlysecure/keychain/EncryptDecryptSymmetricTests.java index f07566755..a97edf5b2 100644 --- a/OpenKeychain/src/androidTest/java/org/sufficientlysecure/keychain/EncryptDecryptSymmetricTests.java +++ b/OpenKeychain/src/androidTest/java/org/sufficientlysecure/keychain/EncryptDecryptSymmetricTests.java @@ -19,8 +19,8 @@ package org.sufficientlysecure.keychain; import android.content.Intent; +import android.support.test.espresso.intent.rule.IntentsTestRule; import android.support.test.espresso.matcher.ViewMatchers; -import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.LargeTest; @@ -29,6 +29,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.MethodSorters; +import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider; import org.sufficientlysecure.keychain.ui.MainActivity; import org.sufficientlysecure.keychain.ui.util.Notify.Style; @@ -40,13 +41,26 @@ import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.typeText; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.contrib.DrawerActions.openDrawer; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.intent.Intents.intended; +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasAction; +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasData; +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasExtra; +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasExtraWithKey; +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasFlags; +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasType; +import static android.support.test.espresso.intent.matcher.UriMatchers.hasHost; +import static android.support.test.espresso.intent.matcher.UriMatchers.hasScheme; +import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant; +import static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.allOf; +import static org.hamcrest.Matchers.equalTo; import static org.sufficientlysecure.keychain.TestHelpers.checkSnackbar; import static org.sufficientlysecure.keychain.TestHelpers.randomString; -import static org.sufficientlysecure.keychain.matcher.DrawableMatcher.withDrawable; +import static org.sufficientlysecure.keychain.matcher.CustomMatchers.isRecyclerItemView; +import static org.sufficientlysecure.keychain.matcher.CustomMatchers.withEncryptionStatus; +import static org.sufficientlysecure.keychain.matcher.CustomMatchers.withSignatureNone; @FixMethodOrder(MethodSorters.NAME_ASCENDING) @@ -57,8 +71,8 @@ public class EncryptDecryptSymmetricTests { public static final String PASSPHRASE = randomString(5, 20); @Rule - public final ActivityTestRule mActivity - = new ActivityTestRule(MainActivity.class) { + public final IntentsTestRule mActivity + = new IntentsTestRule(MainActivity.class) { @Override protected Intent getActivityIntent() { Intent intent = super.getActivityIntent(); @@ -68,9 +82,9 @@ public class EncryptDecryptSymmetricTests { }; @Test - public void testSymmetricTextEncryptDecrypt() throws Exception { + public void testSymmetricCryptClipboard() throws Exception { - MainActivity activity = mActivity.getActivity(); + mActivity.getActivity(); String text = randomString(10, 30); @@ -108,25 +122,67 @@ public class EncryptDecryptSymmetricTests { onView(withId(R.id.passphrase_passphrase)).perform(typeText(PASSPHRASE)); onView(withText(R.string.btn_unlock)).perform(click()); - onView(withId(R.id.decrypt_text_plaintext)).check(matches( - withText(text))); + onView(isRecyclerItemView(R.id.decrypted_files_list, + hasDescendant(withText(R.string.filename_unknown_text)))) + .check(matches(allOf(withEncryptionStatus(true), withSignatureNone()))); - // TODO write generic status verifier + onView(allOf(isDescendantOfA(isRecyclerItemView(R.id.decrypted_files_list, + hasDescendant(withText(R.string.filename_unknown_text)))), + withId(R.id.file))).perform(click()); - onView(withId(R.id.result_encryption_text)).check(matches( - withText(R.string.decrypt_result_encrypted))); - onView(withId(R.id.result_signature_text)).check(matches( - withText(R.string.decrypt_result_no_signature))); - onView(withId(R.id.result_signature_layout)).check(matches( - not(isDisplayed()))); - - onView(withId(R.id.result_encryption_icon)).check(matches( - withDrawable(R.drawable.status_lock_closed_24dp))); - onView(withId(R.id.result_signature_icon)).check(matches( - withDrawable(R.drawable.status_signature_unknown_cutout_24dp))); + intended(allOf( + hasAction("android.intent.action.CHOOSER"), + hasExtra(equalTo(Intent.EXTRA_INTENT), allOf( + hasAction(Intent.ACTION_VIEW), + hasFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION), + hasData(allOf(hasScheme("content"), hasHost(TemporaryStorageProvider.CONTENT_AUTHORITY))), + hasType("text/plain") + )) + )); } } + @Test + public void testSymmetricCryptShare() throws Exception { + + mActivity.getActivity(); + + String text = randomString(10, 30); + + // navigate to encrypt/decrypt + openDrawer(R.id.drawer_layout); + onView(ViewMatchers.withText(R.string.nav_encrypt_decrypt)).perform(click()); + onView(withId(R.id.encrypt_text)).perform(click()); + + { + onView(withId(R.id.encrypt_text_text)).perform(typeText(text)); + + openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext()); + onView(withText(R.string.label_symmetric)).perform(click()); + + onView(withId(R.id.passphrase)).perform(typeText(PASSPHRASE)); + + onView(withId(R.id.passphraseAgain)).perform(typeText(PASSPHRASE)); + + onView(withId(R.id.encrypt_text_text)).check(matches(withText(text))); + + onView(withId(R.id.encrypt_share)).perform(click()); + + } + + intended(allOf( + hasAction("android.intent.action.CHOOSER"), + hasExtra(equalTo(Intent.EXTRA_INTENT), allOf( + hasAction(Intent.ACTION_SEND), + hasFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION), + hasExtraWithKey(Intent.EXTRA_TEXT), + hasType("text/plain") + )) + )); + + } + + } diff --git a/OpenKeychain/src/androidTest/java/org/sufficientlysecure/keychain/matcher/CustomMatchers.java b/OpenKeychain/src/androidTest/java/org/sufficientlysecure/keychain/matcher/CustomMatchers.java index 1db902c4c..42f8d8849 100644 --- a/OpenKeychain/src/androidTest/java/org/sufficientlysecure/keychain/matcher/CustomMatchers.java +++ b/OpenKeychain/src/androidTest/java/org/sufficientlysecure/keychain/matcher/CustomMatchers.java @@ -19,18 +19,46 @@ package org.sufficientlysecure.keychain.matcher; +import java.util.EnumSet; + import android.support.annotation.ColorRes; +import android.support.annotation.IdRes; +import android.support.test.espresso.Espresso; +import android.support.test.espresso.ViewInteraction; +import android.support.test.espresso.assertion.ViewAssertions; import android.support.test.espresso.matcher.BoundedMatcher; +import android.support.test.espresso.matcher.ViewMatchers; +import android.support.v7.widget.CardView; +import android.support.v7.widget.RecyclerView; import android.view.View; +import android.widget.ViewAnimator; import com.nispok.snackbar.Snackbar; +import org.hamcrest.CoreMatchers; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.sufficientlysecure.keychain.EncryptKeyCompletionViewTest; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.ui.DecryptListFragment; +import org.sufficientlysecure.keychain.ui.DecryptListFragment.ViewHolder; import org.sufficientlysecure.keychain.ui.adapter.KeyAdapter.KeyItem; +import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.widget.EncryptKeyCompletionView; +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant; +import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom; +import static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withChild; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withParent; +import static android.support.test.espresso.matcher.ViewMatchers.withText; import static android.support.test.internal.util.Checks.checkNotNull; +import static org.hamcrest.CoreMatchers.allOf; +import static org.hamcrest.CoreMatchers.not; +import static org.sufficientlysecure.keychain.matcher.DrawableMatcher.withDrawable; public abstract class CustomMatchers { @@ -80,5 +108,57 @@ public abstract class CustomMatchers { }; } + public static Matcher withRecyclerView(@IdRes int viewId) { + return allOf(isAssignableFrom(RecyclerView.class), withId(viewId)); + } + + public static Matcher isRecyclerItemView(@IdRes int recyclerId, Matcher specificChildMatcher) { + return allOf(withParent(withRecyclerView(recyclerId)), specificChildMatcher); + } + + public static Matcher withEncryptionStatus(boolean encrypted) { + + if (encrypted) { + return allOf( + hasDescendant(allOf( + withId(R.id.result_encryption_text), withText(R.string.decrypt_result_encrypted))), + hasDescendant(allOf( + withId(R.id.result_encryption_icon), withDrawable(R.drawable.status_lock_closed_24dp, true))) + ); + } else { + return allOf( + hasDescendant(allOf( + withId(R.id.result_encryption_text), withText(R.string.decrypt_result_encrypted))), + hasDescendant(allOf( + withId(R.id.result_encryption_icon), withDrawable(R.drawable.status_lock_open_24dp, true))) + ); + } + } + + public static Matcher withSignatureNone() { + + return allOf( + hasDescendant(allOf( + withId(R.id.result_signature_text), withText(R.string.decrypt_result_no_signature))), + hasDescendant(allOf( + withId(R.id.result_signature_icon), withDrawable(R.drawable.status_signature_invalid_cutout_24dp, true))), + hasDescendant(allOf( + withId(R.id.result_signature_layout), not(isDisplayed()))) + ); + + } + + public static Matcher withSignatureMyKey() { + + return allOf( + hasDescendant(allOf( + withId(R.id.result_signature_text), withText(R.string.decrypt_result_signature_secret))), + hasDescendant(allOf( + withId(R.id.result_signature_icon), withDrawable(R.drawable.status_signature_verified_cutout_24dp, true))), + hasDescendant(allOf( + withId(R.id.result_signature_layout), isDisplayed())) + ); + + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java index 036fbe8c5..1366e5563 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptListFragment.java @@ -387,6 +387,7 @@ public class DecryptListFragment Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(outputUri, "text/plain"); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); return intent; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java index 11524aa08..a3cd63d13 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java @@ -457,8 +457,8 @@ public class KeyFormattingUtils { } int encColorRes = context.getResources().getColor(encColor); - holder.getEncryptionStatusIcon().setImageDrawable(context.getResources().getDrawable(encIcon)); holder.getEncryptionStatusIcon().setColorFilter(encColorRes, PorterDuff.Mode.SRC_IN); + holder.getEncryptionStatusIcon().setImageDrawable(context.getResources().getDrawable(encIcon)); holder.getEncryptionStatusText().setText(encText); holder.getEncryptionStatusText().setTextColor(encColorRes); } @@ -542,8 +542,8 @@ public class KeyFormattingUtils { } int sigColorRes = context.getResources().getColor(sigColor); - holder.getSignatureStatusIcon().setImageDrawable(context.getResources().getDrawable(sigIcon)); holder.getSignatureStatusIcon().setColorFilter(sigColorRes, PorterDuff.Mode.SRC_IN); + holder.getSignatureStatusIcon().setImageDrawable(context.getResources().getDrawable(sigIcon)); holder.getSignatureStatusText().setText(sigText); holder.getSignatureStatusText().setTextColor(sigColorRes); diff --git a/OpenKeychain/src/main/res/layout/decrypt_files_list_fragment.xml b/OpenKeychain/src/main/res/layout/decrypt_files_list_fragment.xml index 8cee4e77a..d9cde05f8 100644 --- a/OpenKeychain/src/main/res/layout/decrypt_files_list_fragment.xml +++ b/OpenKeychain/src/main/res/layout/decrypt_files_list_fragment.xml @@ -13,7 +13,6 @@