-
Notifications
You must be signed in to change notification settings - Fork 193
MSC4075 Use expirationTS to define the call ringing window #4521
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #4521 +/- ##
===========================================
- Coverage 79.16% 78.95% -0.22%
===========================================
Files 836 839 +3
Lines 78758 79506 +748
===========================================
+ Hits 62346 62770 +424
- Misses 16412 16736 +324
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
c1e8df2
to
6a85119
Compare
|
|
||
let pkPushPayloadMock = PKPushPayloadMock().addSeconds(currentDate, lifetime: 30) | ||
|
||
service.pushRegistry(pushRegistry, didReceiveIncomingPushWith: pkPushPayloadMock, for: .voIP) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would've moved everything in ElementCallService.pushRegistry(didReceiveIncomingPushWith)
to a separate method taking just they payload's dictionary. We don't actually need anything else and there's no reason to involve CallKit in the unit tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't actually need anything else and there's no reason to involve CallKit in the unit tests.
Given the intention to test the timeouts, I think we need to involve CallKit here to assert the timeout properly?
init(callProvider: CXProviderProtocol? = nil, timeClock: Time? = nil) { | ||
pushRegistry = PKPushRegistry(queue: nil) | ||
|
||
self.timeClock = timeClock ?? Time(clock: ContinuousClock(), nowDate: Date.init) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not make it the default value in the constructor parameter directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice if the struct properties have default values too. Then the constructor could be timeClock: Time = Time()
Clocks: | ||
url: https://github.com/pointfreeco/swift-clocks | ||
from: 1.0.6 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big fan of non "native" solutions for root problems and more so of code from pointfreeco
. We should figure out a solution that doesn't bring in a third party component for something as core as this, even if it's our own component.
In this particular case though I don't think we need any of that:
- let's have that new version of that
pushRegistry(didReceiveIncomingPushWith)
method expose a cancellation callback - pass in a significant but small timeout in the dictionary payload
- an
expectation
that we.fulfill()
in the callback together withwaitForExpectations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big fan of non "native" solutions for root problems and more so of code from pointfreeco. We should figure out a solution that doesn't bring in a third party component for something as core as this, even if it's our own component.
Tbh, I think it would be nice to have this kind of testable clock infrastructure. I'd be happy if we implemented it ourselves but let's leave that as an exercise for us though, once this is merged?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Chatted with Stefan about this a bit more. I think we're happy over all with introducing the clocks library for now and we can implement something ourselves later to avoid the dependency.
Just a few comments below 👇
let payload = [ElementCallServiceNotificationKey.roomID.rawValue: roomID, | ||
ElementCallServiceNotificationKey.roomDisplayName.rawValue: roomDisplayName, | ||
ElementCallServiceNotificationKey.rtcNotifyEventID.rawValue: rtcNotifyEventID] | ||
ElementCallServiceNotificationKey.expirationTimestampMillis.rawValue: expirationTimestamp, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we convert this to a Date
here…
guard let expirationTimestamp = (payload.dictionaryPayload[ElementCallServiceNotificationKey.expirationTimestampMillis.rawValue] as? NSNumber)?.uint64Value else { | ||
MXLog.error("Something went wrong, missing expiration timestamp for incoming voip call: \(payload)") | ||
return | ||
} | ||
let nowTimestampMillis = UInt64(timeClock.nowDate().timeIntervalSince1970 * 1000) | ||
|
||
guard nowTimestampMillis < expirationTimestamp else { | ||
MXLog.warning("Call expired for room \(roomID), ignoring incoming push") | ||
return | ||
} | ||
|
||
let ringDurationMillis = min(expirationTimestamp - nowTimestampMillis, 90000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And then handle all of this using Date
comparisons rather than millis
so everything is typed properly.
|
||
let pkPushPayloadMock = PKPushPayloadMock().addSeconds(currentDate, lifetime: 30) | ||
|
||
service.pushRegistry(pushRegistry, didReceiveIncomingPushWith: pkPushPayloadMock, for: .voIP) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't actually need anything else and there's no reason to involve CallKit in the unit tests.
Given the intention to test the timeouts, I think we need to involve CallKit here to assert the timeout properly?
// Keep this class testable | ||
struct Time { | ||
var clock: any Clock<Duration> | ||
var nowDate: () -> Date |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can call this now
, so it aligns with Date.now
, Clock.continuous.now
etc.
return CXProvider(configuration: configuration) | ||
}() | ||
private let callProvider: CXProviderProtocol | ||
private let timeClock: Time |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And maybe align the names of these. so time: Time
or maybe timeProvider: TimeProvider
.
init(callProvider: CXProviderProtocol? = nil, timeClock: Time? = nil) { | ||
pushRegistry = PKPushRegistry(queue: nil) | ||
|
||
self.timeClock = timeClock ?? Time(clock: ContinuousClock(), nowDate: Date.init) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice if the struct properties have default values too. Then the constructor could be timeClock: Time = Time()
Clocks: | ||
url: https://github.com/pointfreeco/swift-clocks | ||
from: 1.0.6 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big fan of non "native" solutions for root problems and more so of code from pointfreeco. We should figure out a solution that doesn't bring in a third party component for something as core as this, even if it's our own component.
Tbh, I think it would be nice to have this kind of testable clock infrastructure. I'd be happy if we implemented it ourselves but let's leave that as an exercise for us though, once this is merged?
dict | ||
} | ||
|
||
func addSeconds(_ from: Date, lifetime: Int) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not important as it's a test, but it would help to follow the code if this was called something like withExpiration
seeing as it doesn't add the seconds to the current timeout.
Also, we should use TimeInterval
here (or Duration
) rather than Int
for clarity.
Pull Request Checklist
As per MSC4075
UI changes have been tested with: