@@ -18,12 +18,15 @@ package org.matrix.android.sdk.common
1818
1919import android.content.Context
2020import android.net.Uri
21+ import android.util.Log
2122import androidx.lifecycle.Observer
2223import androidx.test.internal.runner.junit4.statement.UiThreadStatement
2324import kotlinx.coroutines.CoroutineDispatcher
2425import kotlinx.coroutines.CoroutineScope
2526import kotlinx.coroutines.Dispatchers
27+ import kotlinx.coroutines.Job
2628import kotlinx.coroutines.SupervisorJob
29+ import kotlinx.coroutines.cancel
2730import kotlinx.coroutines.delay
2831import kotlinx.coroutines.launch
2932import kotlinx.coroutines.runBlocking
@@ -38,7 +41,10 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationResult
3841import org.matrix.android.sdk.api.session.Session
3942import org.matrix.android.sdk.api.session.events.model.EventType
4043import org.matrix.android.sdk.api.session.events.model.toModel
44+ import org.matrix.android.sdk.api.session.getRoomSummary
4145import org.matrix.android.sdk.api.session.room.Room
46+ import org.matrix.android.sdk.api.session.room.failure.JoinRoomFailure
47+ import org.matrix.android.sdk.api.session.room.model.Membership
4248import org.matrix.android.sdk.api.session.room.model.message.MessageContent
4349import org.matrix.android.sdk.api.session.room.send.SendState
4450import org.matrix.android.sdk.api.session.room.timeline.Timeline
@@ -47,14 +53,15 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
4753import org.matrix.android.sdk.api.session.sync.SyncState
4854import timber.log.Timber
4955import java.util.UUID
56+ import java.util.concurrent.CancellationException
5057import java.util.concurrent.CountDownLatch
5158import java.util.concurrent.TimeUnit
5259
5360/* *
5461 * This class exposes methods to be used in common cases
5562 * Registration, login, Sync, Sending messages...
5663 */
57- class CommonTestHelper private constructor(context : Context ) {
64+ class CommonTestHelper internal constructor(context : Context ) {
5865
5966 companion object {
6067 internal fun runSessionTest (context : Context , autoSignoutOnClose : Boolean = true, block : (CommonTestHelper ) -> Unit ) {
@@ -241,6 +248,37 @@ class CommonTestHelper private constructor(context: Context) {
241248 return sentEvents
242249 }
243250
251+ fun waitForAndAcceptInviteInRoom (otherSession : Session , roomID : String ) {
252+ waitWithLatch { latch ->
253+ retryPeriodicallyWithLatch(latch) {
254+ val roomSummary = otherSession.getRoomSummary(roomID)
255+ (roomSummary != null && roomSummary.membership == Membership .INVITE ).also {
256+ if (it) {
257+ Log .v(" # TEST" , " ${otherSession.myUserId} can see the invite" )
258+ }
259+ }
260+ }
261+ }
262+
263+ // not sure why it's taking so long :/
264+ runBlockingTest(90_000 ) {
265+ Log .v(" #E2E TEST" , " ${otherSession.myUserId} tries to join room $roomID " )
266+ try {
267+ otherSession.roomService().joinRoom(roomID)
268+ } catch (ex: JoinRoomFailure .JoinedWithTimeout ) {
269+ // it's ok we will wait after
270+ }
271+ }
272+
273+ Log .v(" #E2E TEST" , " ${otherSession.myUserId} waiting for join echo ..." )
274+ waitWithLatch {
275+ retryPeriodicallyWithLatch(it) {
276+ val roomSummary = otherSession.getRoomSummary(roomID)
277+ roomSummary != null && roomSummary.membership == Membership .JOIN
278+ }
279+ }
280+ }
281+
244282 /* *
245283 * Reply in a thread
246284 * @param room the room where to send the messages
@@ -285,6 +323,8 @@ class CommonTestHelper private constructor(context: Context) {
285323 )
286324 assertNotNull(session)
287325 return session.also {
326+ // most of the test was created pre-MSC3061 so ensure compatibility
327+ it.cryptoService().enableShareKeyOnInvite(false )
288328 trackedSessions.add(session)
289329 }
290330 }
@@ -428,16 +468,26 @@ class CommonTestHelper private constructor(context: Context) {
428468 * @param latch
429469 * @throws InterruptedException
430470 */
431- fun await (latch : CountDownLatch , timeout : Long? = TestConstants .timeOutMillis) {
471+ fun await (latch : CountDownLatch , timeout : Long? = TestConstants .timeOutMillis, job : Job ? = null ) {
432472 assertTrue(
433473 " Timed out after " + timeout + " ms waiting for something to happen. See stacktrace for cause." ,
434- latch.await(timeout ? : TestConstants .timeOutMillis, TimeUnit .MILLISECONDS )
474+ latch.await(timeout ? : TestConstants .timeOutMillis, TimeUnit .MILLISECONDS ).also {
475+ if (! it) {
476+ // cancel job on timeout
477+ job?.cancel(" Await timeout" )
478+ }
479+ }
435480 )
436481 }
437482
438483 suspend fun retryPeriodicallyWithLatch (latch : CountDownLatch , condition : (() -> Boolean )) {
439484 while (true ) {
440- delay(1000 )
485+ try {
486+ delay(1000 )
487+ } catch (ex: CancellationException ) {
488+ // the job was canceled, just stop
489+ return
490+ }
441491 if (condition()) {
442492 latch.countDown()
443493 return
@@ -447,10 +497,10 @@ class CommonTestHelper private constructor(context: Context) {
447497
448498 fun waitWithLatch (timeout : Long? = TestConstants .timeOutMillis, dispatcher : CoroutineDispatcher = Dispatchers .Main , block : suspend (CountDownLatch ) -> Unit ) {
449499 val latch = CountDownLatch (1 )
450- coroutineScope.launch(dispatcher) {
500+ val job = coroutineScope.launch(dispatcher) {
451501 block(latch)
452502 }
453- await(latch, timeout)
503+ await(latch, timeout, job )
454504 }
455505
456506 fun <T > runBlockingTest (timeout : Long = TestConstants .timeOutMillis, block : suspend () -> T ): T {
0 commit comments