@@ -39,6 +39,8 @@ import io.element.android.libraries.push.test.notifications.FakeImageLoaderHolde
39
39
import io.element.android.libraries.push.test.notifications.FakeOnMissedCallNotificationHandler
40
40
import io.element.android.libraries.push.test.notifications.push.FakeNotificationBitmapLoader
41
41
import io.element.android.services.appnavstate.test.FakeAppForegroundStateService
42
+ import io.element.android.services.toolbox.test.systemclock.A_FAKE_TIMESTAMP
43
+ import io.element.android.services.toolbox.test.systemclock.FakeSystemClock
42
44
import io.element.android.tests.testutils.lambda.lambdaRecorder
43
45
import io.element.android.tests.testutils.lambda.value
44
46
import io.element.android.tests.testutils.plantTestTimber
@@ -368,6 +370,83 @@ class DefaultActiveCallManagerTest {
368
370
assertThat(manager.activeCall.value).isNotNull()
369
371
}
370
372
373
+ @OptIn(ExperimentalCoroutinesApi ::class )
374
+ @Test
375
+ fun `IncomingCall - rings no longer than expiration time` () = runTest {
376
+ setupShadowPowerManager()
377
+ val notificationManagerCompat = mockk<NotificationManagerCompat >(relaxed = true )
378
+ val clock = FakeSystemClock ()
379
+ val manager = createActiveCallManager(notificationManagerCompat = notificationManagerCompat, systemClock = clock)
380
+
381
+ assertThat(manager.activeWakeLock?.isHeld).isFalse()
382
+ assertThat(manager.activeCall.value).isNull()
383
+
384
+ val eventTimestamp = A_FAKE_TIMESTAMP
385
+ // The call should not ring more than 30 seconds after the initial event was sent
386
+ val expirationTimestamp = eventTimestamp + 30_000
387
+
388
+ val callNotificationData = aCallNotificationData(
389
+ timestamp = eventTimestamp,
390
+ expirationTimestamp = expirationTimestamp,
391
+ )
392
+
393
+ // suppose it took 10s to be notified
394
+ clock.epochMillisResult = eventTimestamp + 10_000
395
+ manager.registerIncomingCall(callNotificationData)
396
+
397
+ assertThat(manager.activeCall.value).isEqualTo(
398
+ ActiveCall (
399
+ callType = CallType .RoomCall (
400
+ sessionId = callNotificationData.sessionId,
401
+ roomId = callNotificationData.roomId,
402
+ ),
403
+ callState = CallState .Ringing (callNotificationData)
404
+ )
405
+ )
406
+
407
+ runCurrent()
408
+
409
+ assertThat(manager.activeWakeLock?.isHeld).isTrue()
410
+ verify { notificationManagerCompat.notify(notificationId, any()) }
411
+
412
+ // advance by 21s it should have stopped ringing
413
+ advanceTimeBy(21_000 )
414
+ runCurrent()
415
+
416
+ verify { notificationManagerCompat.cancel(any()) }
417
+ }
418
+ @OptIn(ExperimentalCoroutinesApi ::class )
419
+ @Test
420
+ fun `IncomingCall - ignore expired ring lifetime` () = runTest {
421
+ setupShadowPowerManager()
422
+ val notificationManagerCompat = mockk<NotificationManagerCompat >(relaxed = true )
423
+ val clock = FakeSystemClock ()
424
+ val manager = createActiveCallManager(notificationManagerCompat = notificationManagerCompat, systemClock = clock)
425
+
426
+ assertThat(manager.activeWakeLock?.isHeld).isFalse()
427
+ assertThat(manager.activeCall.value).isNull()
428
+
429
+ val eventTimestamp = A_FAKE_TIMESTAMP
430
+ // The call should not ring more than 30 seconds after the initial event was sent
431
+ val expirationTimestamp = eventTimestamp + 30_000
432
+
433
+ val callNotificationData = aCallNotificationData(
434
+ timestamp = eventTimestamp,
435
+ expirationTimestamp = expirationTimestamp,
436
+ )
437
+
438
+ // suppose it took 35s to be notified
439
+ clock.epochMillisResult = eventTimestamp + 35_000
440
+ manager.registerIncomingCall(callNotificationData)
441
+
442
+ assertThat(manager.activeCall.value).isNull()
443
+
444
+ runCurrent()
445
+
446
+ assertThat(manager.activeWakeLock?.isHeld).isFalse()
447
+ verify(exactly = 0 ) { notificationManagerCompat.notify(notificationId, any()) }
448
+ }
449
+
371
450
private fun setupShadowPowerManager () {
372
451
shadowOf(InstrumentationRegistry .getInstrumentation().targetContext.getSystemService<PowerManager >()).apply {
373
452
setIsWakeLockLevelSupported(PowerManager .PARTIAL_WAKE_LOCK , true )
@@ -378,6 +457,7 @@ class DefaultActiveCallManagerTest {
378
457
matrixClientProvider : FakeMatrixClientProvider = FakeMatrixClientProvider (),
379
458
onMissedCallNotificationHandler : FakeOnMissedCallNotificationHandler = FakeOnMissedCallNotificationHandler (),
380
459
notificationManagerCompat : NotificationManagerCompat = mockk(relaxed = true),
460
+ systemClock : FakeSystemClock = FakeSystemClock (),
381
461
) = DefaultActiveCallManager (
382
462
context = InstrumentationRegistry .getInstrumentation().targetContext,
383
463
coroutineScope = backgroundScope,
@@ -393,5 +473,6 @@ class DefaultActiveCallManagerTest {
393
473
defaultCurrentCallService = DefaultCurrentCallService (),
394
474
appForegroundStateService = FakeAppForegroundStateService (),
395
475
imageLoaderHolder = FakeImageLoaderHolder (),
476
+ systemClock = systemClock,
396
477
)
397
478
}
0 commit comments