diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/Util.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/Util.kt new file mode 100644 index 0000000000..2970dec29a --- /dev/null +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/Util.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk + +import junit.framework.TestCase.fail + +/** + * Will fail the test if invoking [block] is not throwing a Throwable. + * + * @param message the failure message, if the block does not throw any Throwable + * @param failureBlock a Lambda to be able to do extra check on the thrown Throwable + * @param block the block to test + */ +internal suspend fun mustFail( + message: String = "must fail", + failureBlock: ((Throwable) -> Unit)? = null, + block: suspend () -> Unit, +) { + val isSuccess = try { + block.invoke() + true + } catch (throwable: Throwable) { + failureBlock?.invoke(throwable) + false + } + + if (isSuccess) { + fail(message) + } +} diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt index 38597269cb..552936971f 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt @@ -62,6 +62,7 @@ import org.matrix.android.sdk.common.RetryTestRule import org.matrix.android.sdk.common.SessionTestParams import org.matrix.android.sdk.common.TestConstants import org.matrix.android.sdk.common.TestMatrixCallback +import org.matrix.android.sdk.mustFail import java.util.concurrent.CountDownLatch @RunWith(JUnit4::class) @@ -525,10 +526,8 @@ class E2eeSanityTests : InstrumentedTest { // Confirm we can decrypt one but not the other testHelper.runBlockingTest { - try { + mustFail(message = "Should not be able to decrypt event") { newBobSession.cryptoService().decryptEvent(firstEventNewBobPov.root, "") - fail("Should not be able to decrypt event") - } catch (_: MXCryptoError) { } } diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt index 1bd2a46381..895f95aeac 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt @@ -21,7 +21,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest import junit.framework.TestCase.assertNotNull import junit.framework.TestCase.assertTrue -import junit.framework.TestCase.fail import org.amshove.kluent.internal.assertEquals import org.junit.Assert import org.junit.Assert.assertNull @@ -47,6 +46,7 @@ import org.matrix.android.sdk.common.CryptoTestHelper import org.matrix.android.sdk.common.RetryTestRule import org.matrix.android.sdk.common.SessionTestParams import org.matrix.android.sdk.common.TestConstants +import org.matrix.android.sdk.mustFail @RunWith(AndroidJUnit4::class) @FixMethodOrder(MethodSorters.JVM) @@ -95,12 +95,10 @@ class KeyShareTests : InstrumentedTest { assertNotNull(receivedEvent) assert(receivedEvent!!.isEncrypted()) - try { - commonTestHelper.runBlockingTest { + commonTestHelper.runBlockingTest { + mustFail { aliceSession2.cryptoService().decryptEvent(receivedEvent.root, "foo") } - fail("should fail") - } catch (failure: Throwable) { } val outgoingRequestsBefore = aliceSession2.cryptoService().getOutgoingRoomKeyRequests() @@ -168,12 +166,10 @@ class KeyShareTests : InstrumentedTest { } } - try { - commonTestHelper.runBlockingTest { + commonTestHelper.runBlockingTest { + mustFail { aliceSession2.cryptoService().decryptEvent(receivedEvent.root, "foo") } - fail("should fail") - } catch (failure: Throwable) { } // Mark the device as trusted diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt index 1c3c6c46e7..13133b726c 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt @@ -42,6 +42,7 @@ import org.matrix.android.sdk.common.MockOkHttpInterceptor import org.matrix.android.sdk.common.RetryTestRule import org.matrix.android.sdk.common.SessionTestParams import org.matrix.android.sdk.common.TestConstants +import org.matrix.android.sdk.mustFail @RunWith(AndroidJUnit4::class) @FixMethodOrder(MethodSorters.JVM) @@ -96,17 +97,19 @@ class WithHeldTests : InstrumentedTest { // ============================= // Bob should not be able to decrypt because the keys is withheld - try { - // .. might need to wait a bit for stability? - testHelper.runBlockingTest { + // .. might need to wait a bit for stability? + testHelper.runBlockingTest { + mustFail( + message = "This session should not be able to decrypt", + failureBlock = { failure -> + val type = (failure as MXCryptoError.Base).errorType + val technicalMessage = failure.technicalMessage + Assert.assertEquals("Error should be withheld", MXCryptoError.ErrorType.KEYS_WITHHELD, type) + Assert.assertEquals("Cause should be unverified", WithHeldCode.UNVERIFIED.value, technicalMessage) + } + ) { bobUnverifiedSession.cryptoService().decryptEvent(eventBobPOV.root, "") } - Assert.fail("This session should not be able to decrypt") - } catch (failure: Throwable) { - val type = (failure as MXCryptoError.Base).errorType - val technicalMessage = failure.technicalMessage - Assert.assertEquals("Error should be withheld", MXCryptoError.ErrorType.KEYS_WITHHELD, type) - Assert.assertEquals("Cause should be unverified", WithHeldCode.UNVERIFIED.value, technicalMessage) } // Let's see if the reply we got from bob first session is unverified @@ -137,17 +140,18 @@ class WithHeldTests : InstrumentedTest { } // Previous message should still be undecryptable (partially withheld session) - try { - // .. might need to wait a bit for stability? - testHelper.runBlockingTest { + // .. might need to wait a bit for stability? + testHelper.runBlockingTest { + mustFail( + message = "This session should not be able to decrypt", + failureBlock = { failure -> + val type = (failure as MXCryptoError.Base).errorType + val technicalMessage = failure.technicalMessage + Assert.assertEquals("Error should be withheld", MXCryptoError.ErrorType.KEYS_WITHHELD, type) + Assert.assertEquals("Cause should be unverified", WithHeldCode.UNVERIFIED.value, technicalMessage) + }) { bobUnverifiedSession.cryptoService().decryptEvent(eventBobPOV.root, "") } - Assert.fail("This session should not be able to decrypt") - } catch (failure: Throwable) { - val type = (failure as MXCryptoError.Base).errorType - val technicalMessage = failure.technicalMessage - Assert.assertEquals("Error should be withheld", MXCryptoError.ErrorType.KEYS_WITHHELD, type) - Assert.assertEquals("Cause should be unverified", WithHeldCode.UNVERIFIED.value, technicalMessage) } testHelper.signOutAndClose(aliceSession) @@ -190,17 +194,18 @@ class WithHeldTests : InstrumentedTest { // Previous message should still be undecryptable (partially withheld session) val eventBobPOV = bobSession.getRoom(testData.roomId)?.getTimelineEvent(eventId) - try { - // .. might need to wait a bit for stability? - testHelper.runBlockingTest { + // .. might need to wait a bit for stability? + testHelper.runBlockingTest { + mustFail( + message = "This session should not be able to decrypt", + failureBlock = { failure -> + val type = (failure as MXCryptoError.Base).errorType + val technicalMessage = failure.technicalMessage + Assert.assertEquals("Error should be withheld", MXCryptoError.ErrorType.KEYS_WITHHELD, type) + Assert.assertEquals("Cause should be unverified", WithHeldCode.NO_OLM.value, technicalMessage) + }) { bobSession.cryptoService().decryptEvent(eventBobPOV!!.root, "") } - Assert.fail("This session should not be able to decrypt") - } catch (failure: Throwable) { - val type = (failure as MXCryptoError.Base).errorType - val technicalMessage = failure.technicalMessage - Assert.assertEquals("Error should be withheld", MXCryptoError.ErrorType.KEYS_WITHHELD, type) - Assert.assertEquals("Cause should be unverified", WithHeldCode.NO_OLM.value, technicalMessage) } // Ensure that alice has marked the session to be shared with bob