mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
MSC4075 Use expirationTS to define the call ringing window (#4652)
* Listen to call decline to stop ringing when declined from other device * MSC4075 Use expirationTS to define the call ringing window * Implement ElementCallService tests. * Update acknowledgements.
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
//
|
||||
// Copyright 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Clocks
|
||||
import PushKit
|
||||
import XCTest
|
||||
|
||||
@testable import ElementX
|
||||
|
||||
@MainActor
|
||||
class ElementCallServiceTests: XCTestCase {
|
||||
var callProvider: CXProviderMock!
|
||||
var currentDate: Date!
|
||||
var testClock: TestClock<Duration>!
|
||||
let pushRegistry = PKPushRegistry(queue: nil)
|
||||
|
||||
var service: ElementCallService!
|
||||
|
||||
func testIncomingCall() async {
|
||||
setupService()
|
||||
|
||||
XCTAssertFalse(callProvider.reportNewIncomingCallWithUpdateCompletionCalled)
|
||||
|
||||
let expectation = XCTestExpectation(description: "Call accepted")
|
||||
|
||||
let pkPushPayloadMock = PKPushPayloadMock().updatingExpiration(currentDate, lifetime: 30)
|
||||
|
||||
service.pushRegistry(pushRegistry, didReceiveIncomingPushWith: pkPushPayloadMock, for: .voIP) {
|
||||
expectation.fulfill()
|
||||
}
|
||||
|
||||
await fulfillment(of: [expectation], timeout: 1)
|
||||
XCTAssertTrue(callProvider.reportNewIncomingCallWithUpdateCompletionCalled)
|
||||
}
|
||||
|
||||
func testCallIsTimingOut() async {
|
||||
setupService()
|
||||
|
||||
XCTAssertFalse(callProvider.reportNewIncomingCallWithUpdateCompletionCalled)
|
||||
|
||||
let expectation = XCTestExpectation(description: "Call accepted")
|
||||
|
||||
let pushPayload = PKPushPayloadMock().updatingExpiration(currentDate, lifetime: 20)
|
||||
|
||||
service.pushRegistry(pushRegistry,
|
||||
didReceiveIncomingPushWith: pushPayload,
|
||||
for: .voIP) {
|
||||
expectation.fulfill()
|
||||
}
|
||||
await fulfillment(of: [expectation], timeout: 1)
|
||||
|
||||
// advance past the timeout
|
||||
await testClock.advance(by: .seconds(30))
|
||||
|
||||
// Call should have ended with unanswered
|
||||
XCTAssertTrue(callProvider.reportCallWithEndedAtReasonCalled)
|
||||
XCTAssertEqual(callProvider.reportCallWithEndedAtReasonReceivedArguments?.reason, .unanswered)
|
||||
}
|
||||
|
||||
func testExpiredRingLifetimeIsIgnored() async {
|
||||
setupService()
|
||||
|
||||
XCTAssertFalse(callProvider.reportNewIncomingCallWithUpdateCompletionCalled)
|
||||
|
||||
let pushPayload = PKPushPayloadMock().updatingExpiration(currentDate, lifetime: 20)
|
||||
|
||||
currentDate = currentDate.addingTimeInterval(60)
|
||||
|
||||
service.pushRegistry(pushRegistry,
|
||||
didReceiveIncomingPushWith: pushPayload,
|
||||
for: .voIP) { }
|
||||
sleep(20)
|
||||
|
||||
XCTAssertTrue(!callProvider.reportNewIncomingCallWithUpdateCompletionCalled)
|
||||
}
|
||||
|
||||
func testLifetimeIsCapped() async {
|
||||
setupService()
|
||||
|
||||
XCTAssertFalse(callProvider.reportNewIncomingCallWithUpdateCompletionCalled)
|
||||
|
||||
let pushPayload = PKPushPayloadMock().updatingExpiration(currentDate, lifetime: 300)
|
||||
|
||||
service.pushRegistry(pushRegistry,
|
||||
didReceiveIncomingPushWith: pushPayload,
|
||||
for: .voIP) { }
|
||||
|
||||
// advance pass the max timeout but below the 300
|
||||
await testClock.advance(by: .seconds(100))
|
||||
|
||||
// Call should have ended with unanswered
|
||||
XCTAssertTrue(callProvider.reportCallWithEndedAtReasonCalled)
|
||||
XCTAssertEqual(callProvider.reportCallWithEndedAtReasonReceivedArguments?.reason, .unanswered)
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private func setupService() {
|
||||
callProvider = CXProviderMock(.init())
|
||||
currentDate = Date()
|
||||
testClock = TestClock()
|
||||
let dateProvider: () -> Date = {
|
||||
self.currentDate
|
||||
}
|
||||
service = ElementCallService(callProvider: callProvider, timeProvider: TimeProvider(clock: testClock, now: dateProvider))
|
||||
}
|
||||
}
|
||||
|
||||
private class PKPushPayloadMock: PKPushPayload {
|
||||
var dict: [AnyHashable: Any] = [:]
|
||||
|
||||
override init() {
|
||||
dict[ElementCallServiceNotificationKey.roomID.rawValue] = "!room:example.com"
|
||||
dict[ElementCallServiceNotificationKey.roomDisplayName.rawValue] = "welcome"
|
||||
dict[ElementCallServiceNotificationKey.rtcNotifyEventID.rawValue] = "$000"
|
||||
dict[ElementCallServiceNotificationKey.expirationDate.rawValue] = Date(timeIntervalSince1970: 10)
|
||||
}
|
||||
|
||||
override var dictionaryPayload: [AnyHashable: Any] {
|
||||
dict
|
||||
}
|
||||
|
||||
func updatingExpiration(_ from: Date, lifetime: TimeInterval) -> Self {
|
||||
dict[ElementCallServiceNotificationKey.expirationDate.rawValue] = from.addingTimeInterval(lifetime)
|
||||
return self
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user