Skip to content

Commit

Permalink
RTN16l tests for RTN15c5 + RTN15h cases.
Browse files Browse the repository at this point in the history
  • Loading branch information
maratal committed Oct 27, 2023
1 parent 2c80712 commit fa74996
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 10 deletions.
4 changes: 4 additions & 0 deletions Test/Test Utilities/TestProxyTransportFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class TestProxyTransportFactory: RealtimeTransportFactory {
// This value will be used by all TestProxyTransportFactory instances created by this factory (including those created before this property is updated).
var networkConnectEvent: ((ARTRealtimeTransport, URL) -> Void)?

var transportCreatedEvent: ((ARTRealtimeTransport) -> Void)?

func transport(withRest rest: ARTRestInternal, options: ARTClientOptions, resumeKey: String?, logger: InternalLog) -> ARTRealtimeTransport {
let webSocketFactory = WebSocketFactory()

Expand All @@ -21,6 +23,8 @@ class TestProxyTransportFactory: RealtimeTransportFactory {

webSocketFactory.testProxyTransport = testProxyTransport

transportCreatedEvent?(testProxyTransport)

return testProxyTransport
}

Expand Down
13 changes: 12 additions & 1 deletion Test/Test Utilities/TestUtilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,13 @@ class AblyTests {
let transportFactory: TestProxyTransportFactory
}

class func newRealtime(_ options: ARTClientOptions) -> RealtimeTestEnvironment {
class func newRealtime(_ options: ARTClientOptions, onTransportCreated event: ((ARTRealtimeTransport) -> Void)? = nil) -> RealtimeTestEnvironment {
let modifiedOptions = options.copy() as! ARTClientOptions

let autoConnect = modifiedOptions.autoConnect
modifiedOptions.autoConnect = false
let transportFactory = TestProxyTransportFactory()
transportFactory.transportCreatedEvent = event
modifiedOptions.testOptions.transportFactory = transportFactory
let realtime = ARTRealtime(options: modifiedOptions)
realtime.internal.setReachabilityClass(TestReachability.self)
Expand Down Expand Up @@ -1215,6 +1216,16 @@ class TestProxyTransport: ARTWebSocketTransport {
self.replacingAcksWithNacks = nil
}
}

func emulateTokenRevokationBeforeConnected() {
setBeforeIncomingMessageModifier { protocolMessage in
if protocolMessage.action == .connected {
protocolMessage.action = .disconnected
protocolMessage.error = .create(withCode: ARTErrorCode.tokenRevoked.intValue, status: 401, message: "Test token revokation")
}
return protocolMessage
}
}

// MARK: ARTWebSocket

Expand Down
88 changes: 79 additions & 9 deletions Test/Tests/RealtimeClientConnectionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3562,32 +3562,102 @@ class RealtimeClientConnectionTests: XCTestCase {
}
}

// RTN16l
func test__200__Connection__Connection_recovery__failures_system_response_to_unrecoverable_token_error() throws {
// RTN16l for (RTN15c5 + RTN15h1)
func test__200a__Connection__Connection_recovery__failures_system_response_to_unrecoverable_token_error() throws {
let test = Test()
let options = try AblyTests.commonAppSetup(for: test)
let client = AblyTests.newRealtime(options).client
expect(client.internal.connection.state).toEventually(equal(.connected), timeout: testTimeout)

let recoverOptions = try AblyTests.commonAppSetup(for: test)
recoverOptions.recover = client.connection.createRecoveryKey()
recoverOptions.autoConnect = false

let key = recoverOptions.key
// set the key to nil so that the client can't sign further token requests
recoverOptions.key = nil
let tokenTtl = 3.0
let tokenDetails = try getTestTokenDetails(for: test, key: key, ttl: tokenTtl)
let tokenDetails = try getTestTokenDetails(for: test, key: key, ttl: 30.0)
recoverOptions.token = tokenDetails.token
let recoverClient = ARTRealtime(options: recoverOptions)

let recoverClient = AblyTests.newRealtime(recoverOptions).client
defer { recoverClient.dispose(); recoverClient.close() }

let transport = recoverClient.internal.transport as! TestProxyTransport
transport.emulateTokenRevokationBeforeConnected()

waitUntil(timeout: testTimeout) { done in
recoverClient.connection.once(.failed) { stateChange in
expect(stateChange.previous).to(equal(ARTRealtimeConnectionState.connected))
expect(stateChange.reason?.code).to(equal(ARTErrorCode.tokenExpired.intValue))
XCTAssertEqual(stateChange.previous, ARTRealtimeConnectionState.connecting)
XCTAssertEqual(recoverClient.connection.errorReason?.code, ARTErrorCode.tokenRevoked.intValue)
done()
}
recoverClient.connect()
recoverClient.connection.once(.connecting) { stateChange in
XCTFail("Should not attempt to connect")
}
}
}

// RTN16l for (RTN15c5 + RTN15h2 success)
func test__200b__Connection__Connection_recovery__failures_system_response_to_unrecoverable_token_error() throws {
let test = Test()
let options = try AblyTests.commonAppSetup(for: test)
let client = AblyTests.newRealtime(options).client
expect(client.internal.connection.state).toEventually(equal(.connected), timeout: testTimeout)

let recoverOptions = try AblyTests.commonAppSetup(for: test)
recoverOptions.recover = client.connection.createRecoveryKey()

let tokenDetails = try getTestTokenDetails(for: test, key: recoverOptions.key, ttl: 30.0)
recoverOptions.token = tokenDetails.token

let recoverClient = AblyTests.newRealtime(recoverOptions).client
defer { recoverClient.dispose(); recoverClient.close() }

let transport = recoverClient.internal.transport as! TestProxyTransport
transport.emulateTokenRevokationBeforeConnected()

waitUntil(timeout: testTimeout) { done in
let partialDone = AblyTests.splitDone(2, done: done)
recoverClient.connection.once(.disconnected) { stateChange in
XCTAssertEqual(stateChange.previous, ARTRealtimeConnectionState.connecting)
partialDone()
}
recoverClient.connection.once(.connected) { stateChange in
partialDone()
}
}
}

// RTN16l for (RTN15c5 + RTN15h2 failure)
func test__200c__Connection__Connection_recovery__failures_system_response_to_unrecoverable_token_error() throws {
let test = Test()
let options = try AblyTests.commonAppSetup(for: test)
let client = AblyTests.newRealtime(options).client
expect(client.internal.connection.state).toEventually(equal(.connected), timeout: testTimeout)

let recoverOptions = try AblyTests.commonAppSetup(for: test)
recoverOptions.recover = client.connection.createRecoveryKey()

let tokenDetails = try getTestTokenDetails(for: test, key: recoverOptions.key, ttl: 30.0)
recoverOptions.token = tokenDetails.token

let recoverClient = AblyTests.newRealtime(recoverOptions, onTransportCreated: { transport in
(transport as! TestProxyTransport).emulateTokenRevokationBeforeConnected()
}).client
defer { recoverClient.dispose(); recoverClient.close() }

waitUntil(timeout: testTimeout) { done in
let partialDone = AblyTests.splitDone(2, done: done)
recoverClient.connection.once(.disconnected) { stateChange in
partialDone()
XCTAssertNil(recoverClient.connection.errorReason)
recoverClient.connection.once(.disconnected) { stateChange in
XCTAssertEqual(recoverClient.connection.errorReason?.code, ARTErrorCode.tokenRevoked.intValue)
partialDone()
}
}
recoverClient.connection.on(.connected) { _ in
XCTFail("Should not be connected")
}
}
}

Expand Down

0 comments on commit fa74996

Please sign in to comment.