-
Notifications
You must be signed in to change notification settings - Fork 26
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
RTN22 #537
RTN22 #537
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2359,7 +2359,6 @@ class RealtimeClientConnection: QuickSpec { | |
} | ||
|
||
waitUntil(timeout: testTimeout) { done in | ||
// Wait for token to expire | ||
client.connection.once(.Connected) { stateChange in | ||
expect(stateChange?.reason).to(beNil()) | ||
done() | ||
|
@@ -3401,6 +3400,137 @@ class RealtimeClientConnection: QuickSpec { | |
} | ||
} | ||
|
||
// RTN22 | ||
it("Ably can request that a connected client re-authenticates by sending the client an AUTH ProtocolMessage") { | ||
let options = AblyTests.commonAppSetup() | ||
options.useTokenAuth = true | ||
let client = ARTRealtime(options: options) | ||
defer { client.dispose(); client.close() } | ||
let channel = client.channels.get("foo") | ||
|
||
waitUntil(timeout: testTimeout) { done in | ||
channel.attach { error in | ||
expect(error).to(beNil()) | ||
done() | ||
} | ||
} | ||
|
||
guard let initialConnectionId = client.connection.id else { | ||
fail("ConnectionId is nil"); return | ||
} | ||
|
||
guard let initialToken = client.auth.tokenDetails?.token else { | ||
fail("Initial token is nil"); return | ||
} | ||
|
||
waitUntil(timeout: testTimeout) { done in | ||
client.connection.once(.Connected) { stateChange in | ||
expect(stateChange?.reason).to(beNil()) | ||
expect(initialToken).toNot(equal(client.auth.tokenDetails?.token)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please check the connection was resumed successfully There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
done() | ||
} | ||
|
||
let authMessage = ARTProtocolMessage() | ||
authMessage.action = .Auth | ||
client.transport?.receive(authMessage) | ||
} | ||
|
||
expect(client.connection.id).to(equal(initialConnectionId)) | ||
|
||
waitUntil(timeout: testTimeout) { done in | ||
let partialDone = AblyTests.splitDone(2, done: done) | ||
let expectedMessage = ARTMessage(name: "ios", data: "message1") | ||
|
||
channel.subscribe() { message in | ||
expect(message.name).to(equal(expectedMessage.name)) | ||
expect(message.data as? String).to(equal(expectedMessage.data as? String)) | ||
partialDone() | ||
} | ||
|
||
let rest = ARTRest(options: AblyTests.clientOptions(key: options.key!)) | ||
rest.channels.get("foo").publish([expectedMessage]) { error in | ||
expect(error).to(beNil()) | ||
partialDone() | ||
} | ||
} | ||
|
||
channel.off() | ||
} | ||
|
||
// RTN22a | ||
it("re-authenticate and resume the connection when the client is forcibly disconnected following a DISCONNECTED message containing an error code in the range 40140 <= code < 40150") { | ||
let options = AblyTests.commonAppSetup() | ||
options.token = getTestToken(key: options.key!, ttl: 5.0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Five seconds isn't a bit too much? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As above. |
||
let client = ARTRealtime(options: options) | ||
defer { client.dispose(); client.close() } | ||
let channel = client.channels.get("foo") | ||
|
||
waitUntil(timeout: testTimeout) { done in | ||
channel.attach { error in | ||
expect(error).to(beNil()) | ||
done() | ||
} | ||
} | ||
|
||
guard let initialConnectionId = client.connection.id else { | ||
fail("ConnectionId is nil"); return | ||
} | ||
|
||
guard let initialToken = client.auth.tokenDetails?.token else { | ||
fail("Initial token is nil"); return | ||
} | ||
|
||
channel.once(.Detached) { _ in | ||
fail("Should not detach channels") | ||
} | ||
|
||
var authorizeMethodCallCount = 0 | ||
let hook = client.auth.testSuite_injectIntoMethodAfter(#selector(client.auth.authorize)) { | ||
authorizeMethodCallCount += 1 | ||
} | ||
defer { hook.remove() } | ||
|
||
waitUntil(timeout: testTimeout) { done in | ||
client.connection.once(.Disconnected) { stateChange in | ||
guard let error = stateChange?.reason else { | ||
fail("Error is nil"); done(); return | ||
} | ||
expect(error.code) == 40142 | ||
done() | ||
} | ||
} | ||
|
||
waitUntil(timeout: testTimeout) { done in | ||
client.connection.once(.Connected) { stateChange in | ||
expect(stateChange?.reason).to(beNil()) | ||
expect(initialToken).toNot(equal(client.auth.tokenDetails?.token)) | ||
done() | ||
} | ||
} | ||
|
||
expect(client.connection.id).to(equal(initialConnectionId)) | ||
expect(authorizeMethodCallCount) == 1 | ||
|
||
waitUntil(timeout: testTimeout) { done in | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this whole block checking? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This block is checking if the channel was resumed successfully (recommended by @mattheworiordan).
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's just a fail safe to make sure that the reauth is in fact working and there is continuity over the channels |
||
let partialDone = AblyTests.splitDone(2, done: done) | ||
let expectedMessage = ARTMessage(name: "ios", data: "message1") | ||
|
||
channel.subscribe() { message in | ||
expect(message.name).to(equal(expectedMessage.name)) | ||
expect(message.data as? String).to(equal(expectedMessage.data as? String)) | ||
partialDone() | ||
} | ||
|
||
let rest = ARTRest(options: AblyTests.clientOptions(key: options.key!)) | ||
rest.channels.get("foo").publish([expectedMessage]) { error in | ||
expect(error).to(beNil()) | ||
partialDone() | ||
} | ||
} | ||
|
||
channel.off() | ||
} | ||
|
||
} | ||
|
||
// https://github.com/ably/ably-ios/issues/454 | ||
|
@@ -3417,8 +3547,7 @@ class RealtimeClientConnection: QuickSpec { | |
let protoMsg = ARTProtocolMessage() | ||
protoMsg.action = .Disconnect | ||
protoMsg.error = ARTErrorInfo.createWithCode(123, message: "test error") | ||
|
||
client.realtimeTransport(client.transport, didReceiveMessage: protoMsg) | ||
client.transport?.receive(protoMsg) | ||
|
||
expect(client.connection.state).to(equal(ARTRealtimeConnectionState.Disconnected)) | ||
expect(client.connection.errorReason).to(equal(protoMsg.error)) | ||
|
@@ -3651,7 +3780,7 @@ class RealtimeClientConnection: QuickSpec { | |
|
||
let authMessage = ARTProtocolMessage() | ||
authMessage.action = .Auth | ||
client.transport.receive(authMessage) | ||
client.transport?.receive(authMessage) | ||
|
||
client.close() | ||
|
||
|
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.
This is racy. The expectation above can pass after this event is fired. The event listener should be set up before. In fact, you can just remove the expectation above and check that the AUTH protocol message was received inside the CONNECTED event listener.
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.
Yes, you're right. Will fix.