diff --git a/Ably.xcodeproj/project.pbxproj b/Ably.xcodeproj/project.pbxproj index 5ece69f76..4397c2da7 100644 --- a/Ably.xcodeproj/project.pbxproj +++ b/Ably.xcodeproj/project.pbxproj @@ -128,6 +128,7 @@ D7588AF41BFF91B800BB8279 /* ARTURLSessionServerTrust.m in Sources */ = {isa = PBXBuildFile; fileRef = D7588AF21BFF91B800BB8279 /* ARTURLSessionServerTrust.m */; }; D77394031C6F6FFE00F5478F /* ARTProtocolMessage+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D77394021C6F6FFE00F5478F /* ARTProtocolMessage+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; D780846E1C68B3E50083009D /* NSObject+TestSuite.m in Sources */ = {isa = PBXBuildFile; fileRef = D780846D1C68B3E50083009D /* NSObject+TestSuite.m */; }; + D79FF2751D901CD50067FA6A /* ARTRealtime+TestSuite.m in Sources */ = {isa = PBXBuildFile; fileRef = D79FF2741D901CD50067FA6A /* ARTRealtime+TestSuite.m */; }; D7B17EE31C07208B00A6958E /* ARTConnectionDetails.h in Headers */ = {isa = PBXBuildFile; fileRef = D7B17EE11C07208B00A6958E /* ARTConnectionDetails.h */; settings = {ATTRIBUTES = (Public, ); }; }; D7B17EE41C07208B00A6958E /* ARTConnectionDetails.m in Sources */ = {isa = PBXBuildFile; fileRef = D7B17EE21C07208B00A6958E /* ARTConnectionDetails.m */; }; D7C1B8771BBEA81A0087B55F /* Auth.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C1B8761BBEA81A0087B55F /* Auth.swift */; }; @@ -361,6 +362,8 @@ D77394021C6F6FFE00F5478F /* ARTProtocolMessage+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ARTProtocolMessage+Private.h"; sourceTree = ""; }; D780846C1C68B3E50083009D /* NSObject+TestSuite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+TestSuite.h"; sourceTree = ""; }; D780846D1C68B3E50083009D /* NSObject+TestSuite.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+TestSuite.m"; sourceTree = ""; }; + D79FF2731D901CD50067FA6A /* ARTRealtime+TestSuite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ARTRealtime+TestSuite.h"; sourceTree = ""; }; + D79FF2741D901CD50067FA6A /* ARTRealtime+TestSuite.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ARTRealtime+TestSuite.m"; sourceTree = ""; }; D7B17EE11C07208B00A6958E /* ARTConnectionDetails.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTConnectionDetails.h; sourceTree = ""; }; D7B17EE21C07208B00A6958E /* ARTConnectionDetails.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTConnectionDetails.m; sourceTree = ""; }; D7C1B8761BBEA81A0087B55F /* Auth.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Auth.swift; sourceTree = ""; }; @@ -464,6 +467,8 @@ 1C1E52E81AB32E6E004A690F /* Realtime */ = { isa = PBXGroup; children = ( + D79FF2731D901CD50067FA6A /* ARTRealtime+TestSuite.h */, + D79FF2741D901CD50067FA6A /* ARTRealtime+TestSuite.m */, 96E408351A38595F00087F77 /* ARTRealtimeAttachTest.m */, 1CC3D94A1AB6FBB60005BEB0 /* ARTRealtimeChannelHistoryTest.m */, 1C1E53011AB373C5004A690F /* ARTRealtimeChannelTest.m */, @@ -1221,6 +1226,7 @@ 1C1E53021AB373C5004A690F /* ARTRealtimeChannelTest.m in Sources */, 1CC3D9571AB700EC0005BEB0 /* ARTRealtimeMessageTest.m in Sources */, 1C1E52F21AB32ED1004A690F /* ARTRestChannelPublishTest.m in Sources */, + D79FF2751D901CD50067FA6A /* ARTRealtime+TestSuite.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Source/ARTAuth.m b/Source/ARTAuth.m index 969ed55c5..5170fd2a5 100644 --- a/Source/ARTAuth.m +++ b/Source/ARTAuth.m @@ -224,8 +224,10 @@ - (void)handleAuthUrlResponse:(NSHTTPURLResponse *)response withData:(NSData *)d ARTTokenRequest *tokenRequest = [_rest.encoders[@"application/json"] decodeTokenRequest:data error:&decodeError]; if (decodeError) { callback(nil, decodeError); - } else { + } else if (tokenRequest) { [tokenRequest toTokenDetails:self callback:callback]; + } else { + callback(nil, [ARTErrorInfo createWithCode:ARTStateAuthUrlIncompatibleContent message:@"content response cannot be used for token request"]); } } else { callback(tokenDetails, nil); diff --git a/Source/ARTRestPresence.m b/Source/ARTRestPresence.m index 5671dc01f..98e7c28ac 100644 --- a/Source/ARTRestPresence.m +++ b/Source/ARTRestPresence.m @@ -135,7 +135,15 @@ - (BOOL)history:(ARTDataQuery *)query callback:(void(^)(__GENERIC(ARTPaginatedRe ARTPaginatedResultResponseProcessor responseProcessor = ^(NSHTTPURLResponse *response, NSData *data) { id encoder = [_channel.rest.encoders objectForKey:response.MIMEType]; - return [encoder decodePresenceMessages:data]; + return [[encoder decodePresenceMessages:data] artMap:^(ARTPresenceMessage *message) { + NSError *error; + message = [message decodeWithEncoder:_channel.dataEncoder error:&error]; + if (error != nil) { + ARTErrorInfo *errorInfo = [ARTErrorInfo wrap:(ARTErrorInfo *)error.userInfo[NSLocalizedFailureReasonErrorKey] prepend:@"Failed to decode data: "]; + [_channel.logger error:@"RS:%p %@", _channel.rest, errorInfo.message]; + } + return message; + }]; }; [ARTPaginatedResult executePaginated:_channel.rest withRequest:request andResponseProcessor:responseProcessor callback:callback]; diff --git a/Source/ARTStatus.h b/Source/ARTStatus.h index 091a256b7..3f37407d9 100644 --- a/Source/ARTStatus.h +++ b/Source/ARTStatus.h @@ -26,6 +26,7 @@ typedef NS_ENUM(NSUInteger, ARTState) { ARTStateNoClientId, ARTStateMismatchedClientId, ARTStateRequestTokenFailed, + ARTStateAuthUrlIncompatibleContent, ARTStateBadConnectionState, ARTStateError = 99999 }; diff --git a/Spec/Auth.swift b/Spec/Auth.swift index 50a3ad339..6aa3582eb 100644 --- a/Spec/Auth.swift +++ b/Spec/Auth.swift @@ -160,7 +160,7 @@ class Auth : QuickSpec { options.autoConnect = false let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } client.setTransportClass(TestProxyTransport.self) client.connect() @@ -1893,6 +1893,10 @@ class Auth : QuickSpec { // Invalid TokenDetails waitUntil(timeout: testTimeout) { done in ARTRest(options: options).auth.authorise(nil, options: nil) { tokenDetails, error in + guard let error = error else { + fail("Error is nil"); done(); return + } + expect(error.code).to(equal(Int(ARTState.AuthUrlIncompatibleContent.rawValue))) expect(tokenDetails).to(beNil()) done() } @@ -2030,7 +2034,7 @@ class Auth : QuickSpec { describe("Reauth") { // RTC8 - it("should use authorise({force: true}) to reauth with a token with a different set of capabilities") { + pending("should use authorise({force: true}) to reauth with a token with a different set of capabilities") { // init ARTRest let restOptions = AblyTests.setupOptions(AblyTests.jsonRestOptions) let rest = ARTRest(options: restOptions) @@ -2059,7 +2063,7 @@ class Auth : QuickSpec { realtimeOptions.clientId = "testClientId" let realtime = ARTRealtime(options:realtimeOptions) - defer { realtime.close() } + defer { realtime.dispose(); realtime.close() } // wait for connected state waitUntil(timeout: testTimeout) { done in diff --git a/Spec/RealtimeClient.swift b/Spec/RealtimeClient.swift index 1b63f220b..f93b0ae2d 100644 --- a/Spec/RealtimeClient.swift +++ b/Spec/RealtimeClient.swift @@ -30,7 +30,7 @@ class RealtimeClient: QuickSpec { // G4 it("All WebSocket connections should include the current API version") { let client = AblyTests.newRealtime(AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in channel.publish(nil, data: "message") { error in diff --git a/Spec/RealtimeClientChannel.swift b/Spec/RealtimeClientChannel.swift index b6bcd6f86..d60ec33fc 100644 --- a/Spec/RealtimeClientChannel.swift +++ b/Spec/RealtimeClientChannel.swift @@ -82,7 +82,7 @@ class RealtimeClientChannel: QuickSpec { // RTL2a it("should implement the EventEmitter and emit events for state changes") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(channel.statesEventEmitter).to(beAKindOf(ARTEventEmitter.self)) @@ -141,7 +141,7 @@ class RealtimeClientChannel: QuickSpec { // RTL2b it("state attribute should be the current state of the channel") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(channel.state).to(equal(ARTRealtimeChannelState.Initialized)) @@ -154,7 +154,7 @@ class RealtimeClientChannel: QuickSpec { // RTL2c it("should contain an ErrorInfo object with details when an error occurs") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let error = AblyTests.newErrorProtocolMessage() @@ -183,7 +183,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() @@ -211,7 +211,7 @@ class RealtimeClientChannel: QuickSpec { it("ATTACHED channel should transition to FAILED") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() @@ -245,7 +245,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() @@ -261,7 +261,7 @@ class RealtimeClientChannel: QuickSpec { it("ATTACHED channel should transition to DETACHED") { let options = AblyTests.commonAppSetup() let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() @@ -281,7 +281,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) let channel = client.channels.get("test") @@ -299,7 +299,7 @@ class RealtimeClientChannel: QuickSpec { it("ATTACHED channel should transition to DETACHED") { let options = AblyTests.commonAppSetup() let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() @@ -321,7 +321,7 @@ class RealtimeClientChannel: QuickSpec { // RTL4a it("if already ATTACHED or ATTACHING nothing is done") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } var errorInfo: ARTErrorInfo? let channel = client.channels.get("test") @@ -351,7 +351,7 @@ class RealtimeClientChannel: QuickSpec { // RTL4e it("DETACHING") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() @@ -370,7 +370,7 @@ class RealtimeClientChannel: QuickSpec { // RTL4g it("FAILED") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() @@ -400,7 +400,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) let transport = client.transport as! TestProxyTransport @@ -421,7 +421,7 @@ class RealtimeClientChannel: QuickSpec { it("CLOSED") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -438,7 +438,7 @@ class RealtimeClientChannel: QuickSpec { it("SUSPENDED") { let client = AblyTests.newRealtime(AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") client.onSuspended() @@ -453,7 +453,7 @@ class RealtimeClientChannel: QuickSpec { it("FAILED") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") client.onError(AblyTests.newErrorProtocolMessage()) @@ -474,7 +474,7 @@ class RealtimeClientChannel: QuickSpec { let options = AblyTests.commonAppSetup() options.autoConnect = false let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(client.connection.state).to(equal(ARTRealtimeConnectionState.Initialized)) @@ -493,7 +493,7 @@ class RealtimeClientChannel: QuickSpec { let options = AblyTests.commonAppSetup() options.autoConnect = false let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -513,7 +513,7 @@ class RealtimeClientChannel: QuickSpec { let options = AblyTests.commonAppSetup() options.disconnectedRetryTimeout = 0.1 let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -539,7 +539,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) let transport = client.transport as! TestProxyTransport @@ -559,7 +559,7 @@ class RealtimeClientChannel: QuickSpec { let options = AblyTests.clientOptions() options.token = getTestToken(capability: "{ \"main\":[\"subscribe\"] }") let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() @@ -583,7 +583,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) let transport = client.transport as! TestProxyTransport @@ -606,7 +606,7 @@ class RealtimeClientChannel: QuickSpec { it("if called with a callback should call it once attached") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -621,7 +621,7 @@ class RealtimeClientChannel: QuickSpec { it("if called with a callback and already attaching should call the callback once attached") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -638,7 +638,7 @@ class RealtimeClientChannel: QuickSpec { it("if called with a callback and already attached should call the callback with nil error") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -658,7 +658,7 @@ class RealtimeClientChannel: QuickSpec { // RTL5a it("if state is INITIALISED, DETACHED or DETACHING nothing is done") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } var errorInfo: ARTErrorInfo? let channel = client.channels.get("test") @@ -698,7 +698,7 @@ class RealtimeClientChannel: QuickSpec { // RTL5b it("results in an error if the connection state is FAILED") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") client.onError(AblyTests.newErrorProtocolMessage()) @@ -719,7 +719,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) let transport = client.transport as! TestProxyTransport @@ -739,7 +739,7 @@ class RealtimeClientChannel: QuickSpec { // RTL5e it("if called with a callback should call it once detached") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -758,7 +758,7 @@ class RealtimeClientChannel: QuickSpec { // RTL5e it("if called with a callback and already detaching should call the callback once detached") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -779,7 +779,7 @@ class RealtimeClientChannel: QuickSpec { // RTL5e it("if called with a callback and already detached should should call the callback with nil error") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -806,7 +806,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) let transport = client.transport as! TestProxyTransport @@ -839,7 +839,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) let transport = client.transport as! TestProxyTransport @@ -862,7 +862,7 @@ class RealtimeClientChannel: QuickSpec { it("FAILED") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() @@ -886,7 +886,7 @@ class RealtimeClientChannel: QuickSpec { let options = AblyTests.commonAppSetup() options.autoConnect = false let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -907,7 +907,7 @@ class RealtimeClientChannel: QuickSpec { let options = AblyTests.commonAppSetup() options.autoConnect = false let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -928,7 +928,7 @@ class RealtimeClientChannel: QuickSpec { let options = AblyTests.commonAppSetup() options.disconnectedRetryTimeout = 0.1 let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -1004,7 +1004,7 @@ class RealtimeClientChannel: QuickSpec { it("when the message is successfully delivered") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in client.connection.on { stateChange in @@ -1031,7 +1031,7 @@ class RealtimeClientChannel: QuickSpec { let options = AblyTests.commonAppSetup() options.token = getTestToken(key: options.key, capability: "{ \"\(ARTChannels_getChannelNamePrefix!())-test\":[\"subscribe\"] }") let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in client.connection.on { stateChange in @@ -1070,7 +1070,7 @@ class RealtimeClientChannel: QuickSpec { let options = AblyTests.commonAppSetup() options.token = getTestToken(key: options.key, capability: "{ \"\(ARTChannels_getChannelNamePrefix!())-channelToSucceed\":[\"subscribe\", \"publish\"], \"\(ARTChannels_getChannelNamePrefix!())-channelToFail\":[\"subscribe\"] }") let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } TotalMessages.succeeded = 0 TotalMessages.failed = 0 @@ -1117,7 +1117,7 @@ class RealtimeClientChannel: QuickSpec { // RTL6c1 it("if the connection is CONNECTED and the channel is ATTACHED then the messages should be published immediately") { let client = AblyTests.newRealtime(AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() @@ -1202,7 +1202,7 @@ class RealtimeClientChannel: QuickSpec { // RTL6c3 it("implicitly attaches the channel; if the channel is in or moves to the FAILED state before the operation succeeds, it should result in an error") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in let protocolError = AblyTests.newErrorProtocolMessage() @@ -1319,7 +1319,7 @@ class RealtimeClientChannel: QuickSpec { let options = AblyTests.commonAppSetup() options.autoConnect = false let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") // Test that the initially queued messages are sent together. @@ -1374,7 +1374,7 @@ class RealtimeClientChannel: QuickSpec { // RTL6e1 it("should have the provided clientId on received message when it was published with clientId") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } expect(client.auth.clientId).to(beNil()) @@ -1400,7 +1400,7 @@ class RealtimeClientChannel: QuickSpec { // RTL6f it("Message#connectionId should match the current Connection#id for all published messages") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1421,7 +1421,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") typealias JSONObject = NSDictionary @@ -1441,7 +1441,7 @@ class RealtimeClientChannel: QuickSpec { it("a name string and data payload") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let expectedResult = "string_data" @@ -1462,7 +1462,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) @@ -1499,7 +1499,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) @@ -1536,7 +1536,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) @@ -1574,7 +1574,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let message = ARTMessage(name: nil, data: "message") @@ -1604,7 +1604,7 @@ class RealtimeClientChannel: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let message = ARTMessage(name: nil, data: "message", clientId: options.clientId!) @@ -1625,7 +1625,7 @@ class RealtimeClientChannel: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1650,7 +1650,7 @@ class RealtimeClientChannel: QuickSpec { completion(getTestTokenDetails(clientId: "john"), nil) } let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let message = ARTMessage(name: nil, data: "message", clientId: "john") waitUntil(timeout: testTimeout) { done in @@ -1671,7 +1671,7 @@ class RealtimeClientChannel: QuickSpec { completion(getTestTokenDetails(clientId: "john"), nil) } let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let message = ARTMessage(name: nil, data: "message", clientId: "tester") waitUntil(timeout: testTimeout) { done in @@ -1688,7 +1688,7 @@ class RealtimeClientChannel: QuickSpec { // RTL6h it("should provide an optional argument that allows the clientId value to be specified") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1714,7 +1714,7 @@ class RealtimeClientChannel: QuickSpec { // RTL7a it("with no arguments subscribes a listener to all messages") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -1738,7 +1738,7 @@ class RealtimeClientChannel: QuickSpec { // RTL7b it("with a single name argument subscribes a listener to only messages whose name member matches the string name") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -1763,7 +1763,7 @@ class RealtimeClientChannel: QuickSpec { it("with a attach callback should subscribe and call the callback when attached") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -1789,7 +1789,7 @@ class RealtimeClientChannel: QuickSpec { // RTL7c it("should implicitly attach the channel") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -1801,7 +1801,7 @@ class RealtimeClientChannel: QuickSpec { // RTL7c it("should result in an error if channel is in the FAILED state") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.onError(AblyTests.newErrorProtocolMessage()) @@ -1830,7 +1830,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } let (keyData, ivData, messages) = AblyTests.loadCryptoTestData(cryptoTest) let testMessage = messages[0] @@ -1897,7 +1897,7 @@ class RealtimeClientChannel: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } let channelOptions = ARTChannelOptions(cipher: ["key":ARTCrypto.generateRandomKey()]) let channel = client.channels.get("test", options: channelOptions) @@ -1975,7 +1975,7 @@ class RealtimeClientChannel: QuickSpec { // RTL8a it("with no arguments unsubscribes the provided listener to all messages if subscribed") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -1997,7 +1997,7 @@ class RealtimeClientChannel: QuickSpec { // RTL8b it("with a single name argument unsubscribes the provided listener if previously subscribed with a name-specific subscription") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") @@ -2072,7 +2072,7 @@ class RealtimeClientChannel: QuickSpec { it("should invoke an error when the untilAttach is specified and the channel is not attached") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let query = ARTRealtimeHistoryQuery() @@ -2099,7 +2099,7 @@ class RealtimeClientChannel: QuickSpec { for caseItem in cases { it("where value is \(caseItem.untilAttach), should pass the querystring param fromSerial with the serial number assigned to the channel") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let testHTTPExecutor = TestProxyHTTPExecutor() @@ -2272,7 +2272,7 @@ class RealtimeClientChannel: QuickSpec { // RTL12 it("attached channel may receive an additional ATTACHED ProtocolMessage") { let client = AblyTests.newRealtime(AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in channel.attach() { error in diff --git a/Spec/RealtimeClientChannels.swift b/Spec/RealtimeClientChannels.swift index c4087b1b2..d9f60848a 100644 --- a/Spec/RealtimeClientChannels.swift +++ b/Spec/RealtimeClientChannels.swift @@ -24,7 +24,7 @@ class RealtimeClientChannels: QuickSpec { // RTS2 it("should exist methods to check if a channel exists or iterate through the existing channels") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } var disposable = [ARTRealtimeChannel]() disposable.append(client.channels.get("test1")) @@ -46,7 +46,7 @@ class RealtimeClientChannels: QuickSpec { // RTS3a it("should create a new Channel if none exists or return the existing one") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } expect(client.channels.collection).to(haveCount(0)) let channel = client.channels.get("test") @@ -60,7 +60,7 @@ class RealtimeClientChannels: QuickSpec { // RTS3b it("should be possible to specify a ChannelOptions") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let options = ARTChannelOptions() let channel = client.channels.get("test", options: options) expect(channel.options).to(beIdenticalTo(options)) @@ -69,7 +69,7 @@ class RealtimeClientChannels: QuickSpec { // RTS3c it("accessing an existing Channel with options should update the options and then return the object") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } expect(client.channels.get("test").options).toNot(beNil()) let options = ARTChannelOptions() let channel = client.channels.get("test", options: options) @@ -82,7 +82,7 @@ class RealtimeClientChannels: QuickSpec { context("release") { it("should release a channel") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.subscribe { _ in diff --git a/Spec/RealtimeClientConnection.swift b/Spec/RealtimeClientConnection.swift index 844b5a5fd..13c519888 100644 --- a/Spec/RealtimeClientConnection.swift +++ b/Spec/RealtimeClientConnection.swift @@ -32,7 +32,7 @@ class RealtimeClientConnection: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } if let transport = client.transport as? TestProxyTransport, let url = transport.lastUrl { expect(url.host).to(equal("realtime.ably.io")) @@ -49,7 +49,7 @@ class RealtimeClientConnection: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in client.connection.on { stateChange in @@ -87,7 +87,7 @@ class RealtimeClientConnection: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in client.connection.on { stateChange in @@ -127,7 +127,7 @@ class RealtimeClientConnection: QuickSpec { expect(options.autoConnect).to(beTrue(), description: "autoConnect should be true by default") let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } // The only way to control this functionality is with the options flag client.connection.on { stateChange in let stateChange = stateChange! @@ -148,7 +148,7 @@ class RealtimeClientConnection: QuickSpec { options.autoConnect = false let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } var waiting = true waitUntil(timeout: testTimeout) { done in @@ -178,7 +178,7 @@ class RealtimeClientConnection: QuickSpec { let options = AblyTests.commonAppSetup() options.autoConnect = false let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in client.connection.once(.Connecting) { _ in guard let webSocketTransport = client.transport as? ARTWebSocketTransport else { @@ -238,7 +238,7 @@ class RealtimeClientConnection: QuickSpec { options.disconnectedRetryTimeout = 0.0 let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let connection = client.connection var events: [ARTRealtimeConnectionState] = [] @@ -310,7 +310,7 @@ class RealtimeClientConnection: QuickSpec { options.autoConnect = false let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let connection = client.connection var events: [ARTRealtimeConnectionState] = [] @@ -346,7 +346,7 @@ class RealtimeClientConnection: QuickSpec { it("should emit states when connection is closed") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) let connection = client.connection - defer { client.close() } + defer { client.dispose(); client.close() } var events: [ARTRealtimeConnectionState] = [] waitUntil(timeout: testTimeout) { done in @@ -383,7 +383,7 @@ class RealtimeClientConnection: QuickSpec { let options = AblyTests.commonAppSetup() options.autoConnect = false let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let connection = client.connection expect(connection.state.rawValue).to(equal(ARTRealtimeConnectionState.Initialized.rawValue), description: "Missing INITIALIZED state") @@ -432,7 +432,7 @@ class RealtimeClientConnection: QuickSpec { it("should have the reason which contains an ErrorInfo") { let options = AblyTests.commonAppSetup() let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let connection = client.connection var errorInfo: ARTErrorInfo? @@ -571,7 +571,7 @@ class RealtimeClientConnection: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in publishFirstTestMessage(client, completion: { error in @@ -600,7 +600,7 @@ class RealtimeClientConnection: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in client.connection.on { stateChange in @@ -642,7 +642,7 @@ class RealtimeClientConnection: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in publishFirstTestMessage(client, completion: { error in @@ -671,7 +671,7 @@ class RealtimeClientConnection: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in client.connection.on { stateChange in @@ -724,7 +724,7 @@ class RealtimeClientConnection: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("channel") channel.attach() @@ -789,7 +789,7 @@ class RealtimeClientConnection: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("channel") let transport = client.transport as! TestProxyTransport @@ -819,7 +819,7 @@ class RealtimeClientConnection: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("channel") let transport = client.transport as! TestProxyTransport @@ -1412,7 +1412,7 @@ class RealtimeClientConnection: QuickSpec { // RTN13a it("should send a ProtocolMessage with action HEARTBEAT and expects a HEARTBEAT message in response") { let client = AblyTests.newRealtime(AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in client.ping() { error in expect(error).to(beNil()) @@ -1427,7 +1427,7 @@ class RealtimeClientConnection: QuickSpec { // RTN13c it("should fail if a HEARTBEAT ProtocolMessage is not received within the default realtime request timeout") { let client = AblyTests.newRealtime(AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in let start = NSDate() let transport = client.transport as! TestProxyTransport @@ -1658,7 +1658,7 @@ class RealtimeClientConnection: QuickSpec { ARTDefault.setRealtimeRequestTimeout(0.5) let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } var start, end: NSDate? waitUntil(timeout: testTimeout) { done in client.connection.on(.Disconnected) { stateChange in @@ -1743,7 +1743,7 @@ class RealtimeClientConnection: QuickSpec { ARTDefault.setRealtimeRequestTimeout(0.1) let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in client.connection.on(.Suspended) { stateChange in @@ -1828,7 +1828,7 @@ class RealtimeClientConnection: QuickSpec { let options = AblyTests.commonAppSetup() options.disconnectedRetryTimeout = 0.1 let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) let expectedConnectionKey = client.connection.key! @@ -1856,7 +1856,7 @@ class RealtimeClientConnection: QuickSpec { let options = AblyTests.commonAppSetup() options.disconnectedRetryTimeout = 1.0 let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) @@ -1884,7 +1884,7 @@ class RealtimeClientConnection: QuickSpec { let options = AblyTests.commonAppSetup() options.disconnectedRetryTimeout = 1.0 let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) @@ -1939,7 +1939,7 @@ class RealtimeClientConnection: QuickSpec { let options = AblyTests.commonAppSetup() options.disconnectedRetryTimeout = 1.0 let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) @@ -1970,7 +1970,7 @@ class RealtimeClientConnection: QuickSpec { let options = AblyTests.commonAppSetup() options.disconnectedRetryTimeout = 1.0 let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) @@ -2051,7 +2051,7 @@ class RealtimeClientConnection: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport.self) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() @@ -2084,7 +2084,7 @@ class RealtimeClientConnection: QuickSpec { let options = AblyTests.commonAppSetup() options.disconnectedRetryTimeout = 0.5 let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") var resumed = false @@ -2122,7 +2122,7 @@ class RealtimeClientConnection: QuickSpec { options.disconnectedRetryTimeout = 1.0 let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -2350,7 +2350,7 @@ class RealtimeClientConnection: QuickSpec { it("Connection#recoveryKey should be composed with the connection key and latest serial received") { let options = AblyTests.commonAppSetup() let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in client.connection.once(.Connected) { _ in @@ -2407,7 +2407,7 @@ class RealtimeClientConnection: QuickSpec { it("Connection#recoveryKey should become becomes null when a connection is explicitly CLOSED or CLOSED") { let options = AblyTests.commonAppSetup() let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in client.connection.once(.Connected) { _ in client.connection.once(.Closed) { _ in @@ -2431,7 +2431,7 @@ class RealtimeClientConnection: QuickSpec { let options = AblyTests.commonAppSetup() options.recover = "99999!xxxxxx-xxxxxxxxx-xxxxxxxxx:-1" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in client.connection.once(.Connected) { stateChange in expect(stateChange!.reason!.message).to(contain("Unable to recover connection")) @@ -2481,7 +2481,7 @@ class RealtimeClientConnection: QuickSpec { } client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in channel.publish(nil, data: "message") { error in @@ -2513,7 +2513,7 @@ class RealtimeClientConnection: QuickSpec { } client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in channel.publish(nil, data: "message") { error in @@ -2588,7 +2588,7 @@ class RealtimeClientConnection: QuickSpec { } client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in channel.publish(nil, data: "message") { error in @@ -2640,7 +2640,7 @@ class RealtimeClientConnection: QuickSpec { } client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in channel.publish(nil, data: "message") { error in @@ -2670,7 +2670,7 @@ class RealtimeClientConnection: QuickSpec { } client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in channel.publish(nil, data: "message") { error in @@ -2712,7 +2712,7 @@ class RealtimeClientConnection: QuickSpec { } client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in channel.publish(nil, data: "message") { error in @@ -2756,7 +2756,6 @@ class RealtimeClientConnection: QuickSpec { } client.connect() - defer { client.close() } expect(urlConnections).toEventually(haveCount(2), timeout: testTimeout) @@ -2945,7 +2944,7 @@ class RealtimeClientConnection: QuickSpec { options.logLevel = .Debug options.disconnectedRetryTimeout = 0.1 let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let transport = client.transport as! TestProxyTransport @@ -2977,7 +2976,7 @@ class RealtimeClientConnection: QuickSpec { let options = AblyTests.commonAppSetup() options.disconnectedRetryTimeout = 0.1 let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let transport = client.transport as! TestProxyTransport @@ -3006,7 +3005,7 @@ class RealtimeClientConnection: QuickSpec { let options = AblyTests.commonAppSetup() options.disconnectedRetryTimeout = 0.1 let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let transport = client.transport as! TestProxyTransport @@ -3051,6 +3050,7 @@ class RealtimeClientConnection: QuickSpec { } afterEach { + client.dispose() client.close() } @@ -3119,7 +3119,7 @@ class RealtimeClientConnection: QuickSpec { options.autoConnect = false client = ARTRealtime(options: options) client.setReachabilityClass(TestReachability.self) - defer { client.close() } + defer { client.dispose(); client.close() } waitUntil(timeout: testTimeout) { done in client.connection.on { stateChange in @@ -3200,7 +3200,7 @@ class RealtimeClientConnection: QuickSpec { it("should encode and decode fixture messages as expected") { let options = AblyTests.commonAppSetup() let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() diff --git a/Spec/RealtimeClientPresence.swift b/Spec/RealtimeClientPresence.swift index 561d632e0..e134df9ca 100644 --- a/Spec/RealtimeClientPresence.swift +++ b/Spec/RealtimeClientPresence.swift @@ -24,7 +24,7 @@ class RealtimeClientPresence: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() @@ -59,7 +59,7 @@ class RealtimeClientPresence: QuickSpec { let client = ARTRealtime(options: options) client.setTransportClass(TestProxyTransport) client.connect() - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() @@ -94,7 +94,7 @@ class RealtimeClientPresence: QuickSpec { } let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") var lastSyncSerial: String? @@ -214,7 +214,7 @@ class RealtimeClientPresence: QuickSpec { // RTP7a it("with no arguments unsubscribes the listener if previously subscribed with an action-specific subscription") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let listener = channel.presence.subscribe { _ in }! @@ -231,7 +231,7 @@ class RealtimeClientPresence: QuickSpec { // RTP5a it("all queued presence messages should fail immediately if the channel enters the FAILED state") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -248,7 +248,7 @@ class RealtimeClientPresence: QuickSpec { // RTP5a it("all queued presence messages should fail immediately if the channel enters the DETACHED state") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -270,7 +270,7 @@ class RealtimeClientPresence: QuickSpec { it("all queued presence messages will be sent immediately and a presence SYNC will be initiated implicitly if a channel enters the ATTACHED state") { let options = AblyTests.commonAppSetup() let client1 = AblyTests.newRealtime(options) - defer { client1.close() } + defer { client1.dispose(); client1.close() } let channel1 = client1.channels.get("room") waitUntil(timeout: testTimeout) { done in @@ -280,29 +280,37 @@ class RealtimeClientPresence: QuickSpec { } } + let client2 = AblyTests.newRealtime(options) + defer { client2.dispose(); client2.close() } + let channel2 = client2.channels.get(channel1.name) + waitUntil(timeout: testTimeout) { done in - delay(0.5) { + channel2.presence.enterClient("Client 2", data: nil) { error in + expect(error).to(beNil()) + expect(channel2.queuedMessages).to(haveCount(0)) + expect(channel2.state).to(equal(ARTRealtimeChannelState.Attached)) + + if channel2.presence.syncComplete { + expect(channel2.presenceMap.members).to(haveCount(2)) + } + else { + expect(channel2.presenceMap.members).to(haveCount(1)) + } + done() } - } - let client2 = AblyTests.newRealtime(options) - defer { client2.close() } - let channel2 = client2.channels.get(channel1.name) - - channel2.presence.enterClient("Client 2", data: nil) { error in - expect(error).to(beNil()) - expect(channel2.queuedMessages).to(haveCount(0)) - expect(channel2.state).to(equal(ARTRealtimeChannelState.Attached)) + expect(channel2.queuedMessages).to(haveCount(1)) + expect(channel2.presence.syncComplete).to(beFalse()) + expect(channel2.presenceMap.members).to(haveCount(0)) } - expect(channel2.queuedMessages).to(haveCount(1)) - expect(channel2.presence.syncComplete).to(beFalse()) + guard let transport = client2.transport as? TestProxyTransport else { + fail("Transport should be a test proxy"); return + } - expect(channel2.presenceMap.members).to(haveCount(0)) + expect(transport.protocolMessagesReceived.filter{ $0.action == .Sync }).to(haveCount(1)) - expect(channel2.state).toEventually(equal(ARTRealtimeChannelState.Attached), timeout: testTimeout) - expect(channel2.presence.syncComplete).toEventually(beTrue(), timeout: testTimeout) expect(channel2.presenceMap.members).to(haveCount(2)) } @@ -345,7 +353,7 @@ class RealtimeClientPresence: QuickSpec { // RTP7b it("with a single action argument unsubscribes the provided listener to all presence messages for that action") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let listener = channel.presence.subscribe(.Present) { _ in }! @@ -362,7 +370,7 @@ class RealtimeClientPresence: QuickSpec { // RTP6c it("should implicitly attach the channel") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(channel.state).to(equal(ARTRealtimeChannelState.Initialized)) @@ -381,7 +389,7 @@ class RealtimeClientPresence: QuickSpec { // RTP6c it("should result in an error if the channel is in the FAILED state") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.onError(AblyTests.newErrorProtocolMessage()) @@ -402,7 +410,7 @@ class RealtimeClientPresence: QuickSpec { // RTP6c it("should result in an error if the channel moves to the FAILED state") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -521,7 +529,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -549,7 +557,7 @@ class RealtimeClientPresence: QuickSpec { // RTP8f it("should result in an error immediately if the client is anonymous") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -570,7 +578,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -594,7 +602,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.onError(AblyTests.newErrorProtocolMessage()) @@ -617,7 +625,7 @@ class RealtimeClientPresence: QuickSpec { // RTP8i it("should result in an error if Ably service determines that the client is unidentified") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -638,7 +646,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -663,7 +671,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -693,7 +701,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(channel.presenceMap.members).to(haveCount(0)) @@ -717,7 +725,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -733,7 +741,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -751,7 +759,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -787,7 +795,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -816,7 +824,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -851,7 +859,7 @@ class RealtimeClientPresence: QuickSpec { } let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") var user50LeaveTimestamp: NSDate? @@ -901,10 +909,10 @@ class RealtimeClientPresence: QuickSpec { // RTP8h it("should result in an error if the client does not have required presence permission") { let options = AblyTests.commonAppSetup() - options.token = getTestToken(capability: "{ \"cannotpresence:john\":[\"publish\"] }") + options.token = getTestToken(clientId: "john", capability: "{ \"cannotpresence:john\":[\"publish\"] }") options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("cannotpresence") waitUntil(timeout: testTimeout) { done in @@ -926,7 +934,7 @@ class RealtimeClientPresence: QuickSpec { // RTP9e it("should result in an error immediately if the client is anonymous") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -942,7 +950,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() @@ -961,7 +969,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.onError(AblyTests.newErrorProtocolMessage()) @@ -977,10 +985,10 @@ class RealtimeClientPresence: QuickSpec { // RTP9e it("should result in an error if the client does not have required presence permission") { let options = AblyTests.clientOptions() - options.token = getTestToken(capability: "{ \"cannotpresence:john\":[\"publish\"] }") + options.token = getTestToken(clientId: "john", capability: "{ \"cannotpresence:john\":[\"publish\"] }") options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("cannotpresence") waitUntil(timeout: testTimeout) { done in @@ -994,7 +1002,7 @@ class RealtimeClientPresence: QuickSpec { // RTP9e it("should result in an error if Ably service determines that the client is unidentified") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1014,7 +1022,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1037,7 +1045,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1064,7 +1072,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(channel.presence.leave("offline")).to(raiseException()) } @@ -1074,7 +1082,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1112,7 +1120,7 @@ class RealtimeClientPresence: QuickSpec { options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(channel.state).to(equal(ARTRealtimeChannelState.Initialized)) @@ -1132,7 +1140,7 @@ class RealtimeClientPresence: QuickSpec { options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.onError(AblyTests.newErrorProtocolMessage()) @@ -1154,7 +1162,7 @@ class RealtimeClientPresence: QuickSpec { // RTP10e it("should result in an error immediately if the client is anonymous") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1170,7 +1178,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1195,7 +1203,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1218,10 +1226,10 @@ class RealtimeClientPresence: QuickSpec { // RTP10e it("should result in an error if the client does not have required presence permission") { let options = AblyTests.clientOptions() - options.token = getTestToken(capability: "{ \"cannotpresence:other\":[\"publish\"] }") + options.token = getTestToken(clientId: "john", capability: "{ \"cannotpresence:other\":[\"publish\"] }") options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("cannotpresence") waitUntil(timeout: testTimeout) { done in @@ -1235,7 +1243,7 @@ class RealtimeClientPresence: QuickSpec { // RTP10e it("should result in an error if Ably service determines that the client is unidentified") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1254,7 +1262,7 @@ class RealtimeClientPresence: QuickSpec { // RTP6c it("should implicitly attach the channel") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(channel.state).to(equal(ARTRealtimeChannelState.Initialized)) @@ -1273,7 +1281,7 @@ class RealtimeClientPresence: QuickSpec { // RTP6c pending("should result in an error if the channel is in the FAILED state") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.onError(AblyTests.newErrorProtocolMessage()) @@ -1290,7 +1298,7 @@ class RealtimeClientPresence: QuickSpec { // RTP6c pending("should result in an error if the channel moves to the FAILED state") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1422,7 +1430,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1453,7 +1461,7 @@ class RealtimeClientPresence: QuickSpec { context(testCase) { it("should implicitly attach the Channel") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(channel.state).to(equal(ARTRealtimeChannelState.Initialized)) @@ -1470,7 +1478,7 @@ class RealtimeClientPresence: QuickSpec { it("should result in an error if the channel is in the FAILED state") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.onError(AblyTests.newErrorProtocolMessage()) @@ -1486,7 +1494,7 @@ class RealtimeClientPresence: QuickSpec { it("should result in an error if the channel moves to the FAILED state") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1507,7 +1515,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.clientId = "john" let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1534,7 +1542,7 @@ class RealtimeClientPresence: QuickSpec { // RTP16a it("all presence messages are published immediately if the connection is CONNECTED") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1554,7 +1562,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.disconnectedRetryTimeout = 1.0 let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(client.options.queueMessages).to(beTrue()) @@ -1583,7 +1591,7 @@ class RealtimeClientPresence: QuickSpec { options.disconnectedRetryTimeout = 1.0 options.queueMessages = false let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(client.options.queueMessages).to(beFalse()) @@ -1610,7 +1618,7 @@ class RealtimeClientPresence: QuickSpec { let options = AblyTests.commonAppSetup() options.autoConnect = false let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(client.options.queueMessages).to(beTrue()) @@ -1635,7 +1643,7 @@ class RealtimeClientPresence: QuickSpec { for (connectionState, performMethod) in cases { it("should result in an error if the connection state is \(connectionState)") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(client.options.queueMessages).to(beTrue()) @@ -1689,7 +1697,7 @@ class RealtimeClientPresence: QuickSpec { } let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") var presenceQueryWasCreated = false @@ -1717,7 +1725,7 @@ class RealtimeClientPresence: QuickSpec { // RTP11b it("should implicitly attach the channel") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(channel.state).to(equal(ARTRealtimeChannelState.Initialized)) @@ -1735,7 +1743,7 @@ class RealtimeClientPresence: QuickSpec { // RTP11b it("should result in an error if the channel is in the FAILED state") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.onError(AblyTests.newErrorProtocolMessage()) @@ -1752,7 +1760,7 @@ class RealtimeClientPresence: QuickSpec { // RTP11b it("should result in an error if the channel moves to the FAILED state") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1782,7 +1790,7 @@ class RealtimeClientPresence: QuickSpec { } let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let query = ARTRealtimePresenceQuery() @@ -1820,7 +1828,7 @@ class RealtimeClientPresence: QuickSpec { } let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let query = ARTRealtimePresenceQuery() @@ -1913,7 +1921,7 @@ class RealtimeClientPresence: QuickSpec { } let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in @@ -1968,7 +1976,7 @@ class RealtimeClientPresence: QuickSpec { it("should invoke an error when the untilAttach is specified and the channel is not attached") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let query = ARTRealtimeHistoryQuery() @@ -1995,7 +2003,7 @@ class RealtimeClientPresence: QuickSpec { for caseItem in cases { it("where value is \(caseItem.untilAttach), should pass the querystring param fromSerial with the serial number assigned to the channel") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") let testHTTPExecutor = TestProxyHTTPExecutor() @@ -2042,7 +2050,7 @@ class RealtimeClientPresence: QuickSpec { } let client = ARTRealtime(options: options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") waitUntil(timeout: testTimeout) { done in channel.attach() { _ in @@ -2092,7 +2100,7 @@ class RealtimeClientPresence: QuickSpec { } let client = AblyTests.newRealtime(options) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") channel.attach() @@ -2116,7 +2124,7 @@ class RealtimeClientPresence: QuickSpec { // RTP14a, RTP14b, RTP14c, RTP14d it("enters into presence on a channel on behalf of another clientId") { let client = ARTRealtime(options: AblyTests.commonAppSetup()) - defer { client.close() } + defer { client.dispose(); client.close() } let channel = client.channels.get("test") expect(channel.presenceMap.members).to(haveCount(0)) diff --git a/Spec/RestClient.swift b/Spec/RestClient.swift index 3af4c32e1..241c9c38a 100644 --- a/Spec/RestClient.swift +++ b/Spec/RestClient.swift @@ -991,14 +991,16 @@ class RestClient: QuickSpec { options.token = getTestToken(ttl: 0.1) let client = ARTRest(options: options) waitUntil(timeout: testTimeout) { done in - client.channels.get("test").publish(nil, data: "message") { error in - guard let error = error else { - fail("Error is empty"); done() - return + delay(0.1) { + client.channels.get("test").publish(nil, data: "message") { error in + guard let error = error else { + fail("Error is empty"); done() + return + } + expect(error.code).to(equal(Int(ARTState.RequestTokenFailed.rawValue))) + expect(error.message).to(contain("no means to renew the token is provided")) + done() } - expect(error.code).to(equal(Int(ARTState.RequestTokenFailed.rawValue))) - expect(error.message).to(contain("no means to renew the token is provided")) - done() } } } diff --git a/Spec/RestClientChannel.swift b/Spec/RestClientChannel.swift index 7d00968f8..c1d611bcf 100644 --- a/Spec/RestClientChannel.swift +++ b/Spec/RestClientChannel.swift @@ -344,8 +344,8 @@ class RestClientChannel: QuickSpec { } } - delay(0.2) { - waitUntil(timeout: testTimeout) { done in + waitUntil(timeout: testTimeout) { done in + delay(0.2) { channel.publish(nil, data: "message3") { _ in done() } diff --git a/Spec/RestClientPresence.swift b/Spec/RestClientPresence.swift index 6d8f65d2c..3124f0ad0 100644 --- a/Spec/RestClientPresence.swift +++ b/Spec/RestClientPresence.swift @@ -477,18 +477,13 @@ class RestClientPresence: QuickSpec { let channel = client.channels.get("test") let expectedData = ["test":1] - var decodeNumberOfCalls = 0 - let hook = ARTBaseMessage.testSuite_injectIntoClassMethod(#selector(ARTBaseMessage.decodeWithEncoder(_:error:))) { - decodeNumberOfCalls += 1 - } - defer { hook?.remove() } waitUntil(timeout: testTimeout) { done in channel.publish(nil, data: expectedData) { _ in done() } } var realtime = ARTRealtime(options: options) - defer { realtime.close() } + defer { realtime.dispose(); realtime.close() } waitUntil(timeout: testTimeout) { done in realtime.channels.get("test").presence.enterClient("john", data: expectedData) { _ in done() } } @@ -503,6 +498,12 @@ class RestClientPresence: QuickSpec { } } + var decodeNumberOfCalls = 0 + let hook = ARTBaseMessage.testSuite_injectIntoClassMethod(#selector(ARTBaseMessage.decodeWithEncoder(_:error:))) { + decodeNumberOfCalls += 1 + } + defer { hook?.remove() } + waitUntil(timeout: testTimeout) { done in channel.history(checkReceivedMessage(done)) } diff --git a/Tests/ARTRealtime+TestSuite.h b/Tests/ARTRealtime+TestSuite.h new file mode 100644 index 000000000..cc23084a8 --- /dev/null +++ b/Tests/ARTRealtime+TestSuite.h @@ -0,0 +1,16 @@ +// +// ARTRealtime+TestSuite.h +// Ably +// +// Created by Ricardo Pereira on 19/09/2016. +// Copyright © 2016 Ably. All rights reserved. +// + +#import +#import "ARTRealtime.h" + +@interface ARTRealtime (TestSuite) + +- (void)testSuite_waitForConnectionToClose:(XCTestCase *)textCase; + +@end diff --git a/Tests/ARTRealtime+TestSuite.m b/Tests/ARTRealtime+TestSuite.m new file mode 100644 index 000000000..2ab3b168d --- /dev/null +++ b/Tests/ARTRealtime+TestSuite.m @@ -0,0 +1,36 @@ +// +// ARTRealtime+TestSuite.m +// Ably +// +// Created by Ricardo Pereira on 19/09/2016. +// Copyright © 2016 Ably. All rights reserved. +// + +#import "ARTRealtime+TestSuite.h" +#import "ARTRealtimeChannel+Private.h" +#import "ARTRealtimeChannels+Private.h" + +@implementation ARTRealtime (TestSuite) + +- (void)testSuite_waitForConnectionToClose:(XCTestCase *)testCase { + if (self.connection.state == ARTRealtimeConnected) { + __weak XCTestExpectation *expectation = [testCase expectationWithDescription:[NSString stringWithFormat:@"%s", __FUNCTION__]]; + + [self.channels.collection enumerateKeysAndObjectsUsingBlock:^(NSString *channelName, ARTRealtimeChannel *channel, BOOL *stop) { + [channel off]; + [channel unsubscribe]; + [channel.presence unsubscribe]; + }]; + [self.connection off]; + + [self.connection once:ARTRealtimeClosed callback:^(ARTConnectionStateChange *stateChange) { + [expectation fulfill]; + }]; + + [self close]; + + [testCase waitForExpectationsWithTimeout:1.0 handler:nil]; + } +} + +@end diff --git a/Tests/ARTRealtimeAttachTest.m b/Tests/ARTRealtimeAttachTest.m index 9834e107c..27ad2dd2f 100644 --- a/Tests/ARTRealtimeAttachTest.m +++ b/Tests/ARTRealtimeAttachTest.m @@ -8,7 +8,7 @@ #import #import - +#import "ARTRealtime+TestSuite.h" #import "ARTRealtime+Private.h" #import "ARTRealtimePresence.h" #import "ARTRealtimeChannel.h" @@ -68,6 +68,7 @@ - (void)testAttachOnce { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testAttachMultipleChannels { @@ -90,6 +91,7 @@ - (void)testAttachMultipleChannels { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testDetach { @@ -112,6 +114,7 @@ - (void)testDetach { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testDetaching { @@ -143,6 +146,7 @@ - (void)testDetaching { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testSkipsFromAttachingToDetaching { @@ -168,6 +172,7 @@ - (void)testSkipsFromAttachingToDetaching { }]; [channel attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } -(void)testDetachingIgnoresDetach { @@ -195,6 +200,7 @@ -(void)testDetachingIgnoresDetach { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testAttachFailsOnFailedConnection { @@ -232,6 +238,7 @@ - (void)testAttachFailsOnFailedConnection { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testAttachRestricted { @@ -255,6 +262,7 @@ - (void)testAttachRestricted { }]; [channel attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testAttachingChannelFails { @@ -273,6 +281,7 @@ - (void)testAttachingChannelFails { }]; [channel1 attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testAttachedChannelFails { @@ -291,6 +300,7 @@ - (void)testAttachedChannelFails { }]; [channel1 attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testChannelClosesOnClose { @@ -309,6 +319,7 @@ - (void)testChannelClosesOnClose { }]; [channel1 attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testPresenceEnterRestricted { @@ -357,6 +368,7 @@ - (void)testPresenceEnterRestricted { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } @end diff --git a/Tests/ARTRealtimeInitTest.m b/Tests/ARTRealtimeInitTest.m index 295f1b53f..f4fcf0494 100644 --- a/Tests/ARTRealtimeInitTest.m +++ b/Tests/ARTRealtimeInitTest.m @@ -7,6 +7,7 @@ // #import #import +#import "ARTRealtime+TestSuite.h" #import "ARTMessage.h" #import "ARTClientOptions.h" #import "ARTPresenceMessage.h" @@ -45,6 +46,7 @@ - (void)testInitWithOptions { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testInitWithHost { @@ -65,6 +67,7 @@ - (void)testInitWithHost { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testInitWithKey { @@ -76,6 +79,7 @@ - (void)testInitWithKey { [expectation fulfill]; } [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testInitAutoConnectDefault { @@ -89,6 +93,7 @@ - (void)testInitAutoConnectDefault { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testInitAutoConnectFalse { @@ -104,6 +109,7 @@ - (void)testInitAutoConnectFalse { }]; [realtime connect]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } @end diff --git a/Tests/ARTRealtimeMessageTest.m b/Tests/ARTRealtimeMessageTest.m index ac4322700..f063c0b52 100644 --- a/Tests/ARTRealtimeMessageTest.m +++ b/Tests/ARTRealtimeMessageTest.m @@ -7,6 +7,7 @@ // #import #import +#import "ARTRealtime+TestSuite.h" #import "ARTMessage.h" #import "ARTClientOptions.h" #import "ARTPresenceMessage.h" @@ -57,7 +58,8 @@ - (void)multipleSendName:(NSString *)name count:(int)count delay:(int)delay { }]; } }]; - [self waitForExpectationsWithTimeout:[ARTTestUtil timeout]+delay handler:nil]; + [self waitForExpectationsWithTimeout:50.0 handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testSingleSendText { @@ -73,6 +75,7 @@ - (void)testSingleSendText { XCTAssertNil(errorInfo); }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testSingleSendEchoText { @@ -122,6 +125,8 @@ - (void)testSingleSendEchoText { [expectation3 fulfill]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout]+5.0 handler:nil]; + [realtime1 testSuite_waitForConnectionToClose:self]; + [realtime2 testSuite_waitForConnectionToClose:self]; } - (void)testPublish_10_1000 { @@ -163,6 +168,8 @@ - (void)testEchoMessagesDefault { }]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; + [realtime2 testSuite_waitForConnectionToClose:self]; } - (void)testEchoMessagesFalse { @@ -190,6 +197,8 @@ - (void)testEchoMessagesFalse { }]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; + [realtime2 testSuite_waitForConnectionToClose:self]; } - (void)testSubscribeAttaches { @@ -206,6 +215,7 @@ - (void)testSubscribeAttaches { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testMessageQueue { @@ -253,9 +263,9 @@ - (void)testMessageQueue { }]; [realtime connect]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - - (void)testConnectionIdsInMessage { ARTClientOptions *options = [ARTTestUtil newSandboxApp:self withDescription:__FUNCTION__]; NSString *channelName = @"channelName"; @@ -285,6 +295,8 @@ - (void)testConnectionIdsInMessage { }]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; + [realtime2 testSuite_waitForConnectionToClose:self]; } - (void)testPublishImmediate { @@ -310,6 +322,7 @@ - (void)testPublishImmediate { [expectation fulfill]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testPublishArray { @@ -338,6 +351,7 @@ - (void)testPublishArray { messageCount++; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testPublishWithName { @@ -354,9 +368,9 @@ - (void)testPublishWithName { [expectation fulfill]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - - (void)testSubscribeToName { ARTClientOptions *options = [ARTTestUtil newSandboxApp:self withDescription:__FUNCTION__]; NSString *channelName = @"channel"; @@ -380,6 +394,7 @@ - (void)testSubscribeToName { }]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } @end diff --git a/Tests/ARTRealtimePresenceHistoryTest.m b/Tests/ARTRealtimePresenceHistoryTest.m index f9d1388aa..2857a34ca 100644 --- a/Tests/ARTRealtimePresenceHistoryTest.m +++ b/Tests/ARTRealtimePresenceHistoryTest.m @@ -7,6 +7,7 @@ // #import #import +#import "ARTRealtime+TestSuite.h" #import "ARTMessage.h" #import "ARTClientOptions.h" #import "ARTPresenceMessage.h" @@ -82,6 +83,7 @@ - (void)runTestLimit:(int)limit forwards:(bool)forwards callback:(void (^)(ARTPa }]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testPresenceHistory { @@ -109,6 +111,7 @@ - (void)testPresenceHistory { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testForward { @@ -156,6 +159,7 @@ - (void)testForward { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testSecondChannel { @@ -209,6 +213,8 @@ - (void)testSecondChannel { }]; [channel attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime1 testSuite_waitForConnectionToClose:self]; + [realtime2 testSuite_waitForConnectionToClose:self]; } - (void)testWaitTextBackward { @@ -262,6 +268,7 @@ - (void)testWaitTextBackward { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testLimitForward { @@ -424,6 +431,7 @@ - (void)runTestTimeForwards:(bool) forwards limit:(int) limit callback:(void (^) [historyExpecation fulfill]; } error:nil]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testTimeForward { @@ -507,6 +515,8 @@ - (void)testFromAttach { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; + [realtime2 testSuite_waitForConnectionToClose:self]; } - (void)testPresenceHistoryMultipleClients { @@ -551,6 +561,9 @@ - (void)testPresenceHistoryMultipleClients { }]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; + [realtime2 testSuite_waitForConnectionToClose:self]; + [realtime3 testSuite_waitForConnectionToClose:self]; } @end diff --git a/Tests/ARTRealtimePresenceTest.m b/Tests/ARTRealtimePresenceTest.m index 133bcfe01..db2435951 100644 --- a/Tests/ARTRealtimePresenceTest.m +++ b/Tests/ARTRealtimePresenceTest.m @@ -7,6 +7,7 @@ // #import #import +#import "ARTRealtime+TestSuite.h" #import "ARTMessage.h" #import "ARTClientOptions.h" #import "ARTPresenceMessage.h" @@ -87,6 +88,8 @@ - (void)testTwoConnections { [expectation3 fulfill]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; + [realtime2 testSuite_waitForConnectionToClose:self]; } - (void)testEnterSimple { @@ -128,6 +131,7 @@ - (void)testEnterSimple { XCTAssertNil(errorInfo); }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testEnterAttachesTheChannel { @@ -144,6 +148,7 @@ - (void)testEnterAttachesTheChannel { }]; [channel attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testSubscribeConnects { @@ -162,6 +167,7 @@ - (void)testSubscribeConnects { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testUpdateConnects { @@ -180,6 +186,7 @@ - (void)testUpdateConnects { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testEnterBeforeConnect { @@ -211,6 +218,7 @@ - (void)testEnterBeforeConnect { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testEnterLeaveSimple { @@ -222,16 +230,19 @@ - (void)testEnterLeaveSimple { __weak XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __FUNCTION__]]; ARTRealtime *realtime = [[ARTRealtime alloc] initWithOptions:options]; ARTRealtimeChannel *channel = [realtime.channels get:channelName]; + void(^partialExpectationFulfill)(void) = [ARTTestUtil splitFulfillFrom:self expectation:expectation in:2]; [channel.presence subscribe:^(ARTPresenceMessage *message) { if(message.action == ARTPresenceEnter) { XCTAssertEqualObjects([message data], presenceEnter); [channel.presence leave:presenceLeave callback:^(ARTErrorInfo *errorInfo) { XCTAssertNil(errorInfo); + // Should wait for the publishing acknowledgement + partialExpectationFulfill(); }]; } if(message.action == ARTPresenceLeave) { XCTAssertEqualObjects([message data], presenceLeave); - [expectation fulfill]; + partialExpectationFulfill(); } }]; @@ -249,6 +260,7 @@ - (void)testEnterLeaveSimple { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testEnterEnter { @@ -260,16 +272,19 @@ - (void)testEnterEnter { __weak XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __FUNCTION__]]; ARTRealtime *realtime = [[ARTRealtime alloc] initWithOptions:options]; ARTRealtimeChannel *channel = [realtime.channels get:channelName]; + void(^partialExpectationFulfill)(void) = [ARTTestUtil splitFulfillFrom:self expectation:expectation in:2]; [channel.presence subscribe:^(ARTPresenceMessage *message) { if(message.action == ARTPresenceEnter) { XCTAssertEqualObjects([message data], presenceEnter); [channel.presence enter:secondEnter callback:^(ARTErrorInfo *errorInfo) { XCTAssertNil(errorInfo); + // Should wait for the publishing acknowledgement + partialExpectationFulfill(); }]; } else if(message.action == ARTPresenceUpdate) { XCTAssertEqualObjects([message data], secondEnter); - [expectation fulfill]; + partialExpectationFulfill(); } }]; [realtime.connection on:^(ARTConnectionStateChange *stateChange) { @@ -286,6 +301,7 @@ - (void)testEnterEnter { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testEnterUpdateSimple { @@ -297,16 +313,19 @@ - (void)testEnterUpdateSimple { __weak XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __FUNCTION__]]; ARTRealtime *realtime = [[ARTRealtime alloc] initWithOptions:options]; ARTRealtimeChannel *channel = [realtime.channels get:channelName]; + void(^partialExpectationFulfill)(void) = [ARTTestUtil splitFulfillFrom:self expectation:expectation in:2]; [channel.presence subscribe:^(ARTPresenceMessage *message) { if(message.action == ARTPresenceEnter) { XCTAssertEqualObjects([message data], presenceEnter); [channel.presence update:update callback:^(ARTErrorInfo *errorInfo) { XCTAssertNil(errorInfo); + // Should wait for the publishing acknowledgement + partialExpectationFulfill(); }]; } else if(message.action == ARTPresenceUpdate) { XCTAssertEqualObjects([message data], update); - [expectation fulfill]; + partialExpectationFulfill(); } }]; [realtime.connection on:^(ARTConnectionStateChange *stateChange) { @@ -323,6 +342,7 @@ - (void)testEnterUpdateSimple { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testUpdateNull { @@ -333,16 +353,19 @@ - (void)testUpdateNull { __weak XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __FUNCTION__]]; ARTRealtime *realtime = [[ARTRealtime alloc] initWithOptions:options]; ARTRealtimeChannel *channel = [realtime.channels get:channelName]; + void(^partialExpectationFulfill)(void) = [ARTTestUtil splitFulfillFrom:self expectation:expectation in:2]; [channel.presence subscribe:^(ARTPresenceMessage *message) { if(message.action == ARTPresenceEnter) { XCTAssertEqualObjects([message data], presenceEnter); [channel.presence update:nil callback:^(ARTErrorInfo *errorInfo) { XCTAssertNil(errorInfo); + // Should wait for the publishing acknowledgement + partialExpectationFulfill(); }]; } else if(message.action == ARTPresenceUpdate) { XCTAssertEqualObjects([message data], nil); - [expectation fulfill]; + partialExpectationFulfill(); } }]; [realtime.connection on:^(ARTConnectionStateChange *stateChange) { @@ -359,6 +382,7 @@ - (void)testUpdateNull { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testEnterLeaveWithoutData { @@ -371,16 +395,19 @@ - (void)testEnterLeaveWithoutData { __weak XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __FUNCTION__]]; ARTRealtime *realtime = [[ARTRealtime alloc] initWithOptions:options]; ARTRealtimeChannel *channel = [realtime.channels get:channelName]; + void(^partialExpectationFulfill)(void) = [ARTTestUtil splitFulfillFrom:self expectation:expectation in:2]; [channel.presence subscribe:^(ARTPresenceMessage *message) { if (message.action == ARTPresenceEnter) { XCTAssertEqualObjects([message data], presenceEnter); [channel.presence leave:@"" callback:^(ARTErrorInfo *errorInfo) { XCTAssertNil(errorInfo); + // Should wait for the publishing acknowledgement + partialExpectationFulfill(); }]; } if (message.action == ARTPresenceLeave) { XCTAssertEqualObjects([message data], presenceEnter); - [expectation fulfill]; + partialExpectationFulfill(); } }]; @@ -399,6 +426,7 @@ - (void)testEnterLeaveWithoutData { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testUpdateNoEnter { @@ -433,6 +461,7 @@ - (void)testUpdateNoEnter { }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testEnterAndGet { @@ -463,6 +492,8 @@ - (void)testEnterAndGet { }]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; + [realtime2 testSuite_waitForConnectionToClose:self]; } - (void)testEnterNoClientId { @@ -475,6 +506,7 @@ - (void)testEnterNoClientId { [expectation fulfill]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testEnterOnDetached { @@ -496,6 +528,7 @@ - (void)testEnterOnDetached { }]; [channel attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testEnterOnFailed { @@ -517,6 +550,7 @@ - (void)testEnterOnFailed { }]; [channel attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testLeaveAndGet { @@ -545,6 +579,7 @@ - (void)testLeaveAndGet { XCTAssertNil(errorInfo); }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testLeaveNoData { @@ -554,16 +589,19 @@ - (void)testLeaveNoData { __weak XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __FUNCTION__]]; ARTRealtime *realtime = [[ARTRealtime alloc] initWithOptions:options]; ARTRealtimeChannel *channel = [realtime.channels get:@"testEnterLeaveNoData"]; + void(^partialExpectationFulfill)(void) = [ARTTestUtil splitFulfillFrom:self expectation:expectation in:2]; [channel.presence subscribe:^(ARTPresenceMessage *message) { if(message.action == ARTPresenceEnter) { XCTAssertEqualObjects([message data], enter); [channel.presence leave:@"" callback:^(ARTErrorInfo *errorInfo) { XCTAssertNil(errorInfo); + // Should wait for the publishing acknowledgement + partialExpectationFulfill(); }]; } else if(message.action == ARTPresenceLeave) { XCTAssertEqualObjects([message data], enter); - [expectation fulfill]; + partialExpectationFulfill(); } }]; [channel attach]; @@ -575,6 +613,7 @@ - (void)testLeaveNoData { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testLeaveNoMessage { @@ -601,6 +640,7 @@ - (void)testLeaveNoMessage { }]; [channel attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testLeaveWithMessage { @@ -628,6 +668,7 @@ - (void)testLeaveWithMessage { }]; [channel attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testLeaveOnDetached { @@ -647,6 +688,7 @@ - (void)testLeaveOnDetached { }]; [channel attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testLeaveOnFailed { @@ -666,6 +708,7 @@ - (void)testLeaveOnFailed { }]; [channel attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testEnterFailsOnError { @@ -688,6 +731,7 @@ - (void)testEnterFailsOnError { }]; [channel attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testGetFailsOnDetachedOrFailed { @@ -714,6 +758,7 @@ - (void)testGetFailsOnDetachedOrFailed { } }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testEnterClient { @@ -739,6 +784,7 @@ - (void)testEnterClient { }]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testEnterClientIdFailsOnError { @@ -759,6 +805,7 @@ - (void)testEnterClientIdFailsOnError { }]; [channel attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testWithNoClientIdUpdateLeaveEnterAnotherClient { @@ -797,6 +844,7 @@ - (void)testWithNoClientIdUpdateLeaveEnterAnotherClient { messageCount++; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testPresenceMap { @@ -833,6 +881,7 @@ - (void)testPresenceMap { }]; [channel2 attach]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testLeaveBeforeEnterThrows { @@ -852,6 +901,7 @@ - (void)testLeaveBeforeEnterThrows { }]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testSubscribeToAction { @@ -902,6 +952,7 @@ - (void)testSubscribeToAction { }]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testPresenceWithData { @@ -923,6 +974,7 @@ - (void)testPresenceWithData { }]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testPresenceWithDataOnLeave { @@ -975,6 +1027,7 @@ - (void)testPresenceWithDataOnLeave { }]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } @end diff --git a/Tests/ARTRealtimeRecoverTest.m b/Tests/ARTRealtimeRecoverTest.m index ed1f0056e..164d9b836 100644 --- a/Tests/ARTRealtimeRecoverTest.m +++ b/Tests/ARTRealtimeRecoverTest.m @@ -7,6 +7,7 @@ // #import #import +#import "ARTRealtime+TestSuite.h" #import "ARTMessage.h" #import "ARTClientOptions.h" #import "ARTPresenceMessage.h" @@ -74,6 +75,7 @@ - (void)testRecoverDisconnected { XCTAssertEqualObjects(realtimeRecovered.connection.id, firstConnectionId); }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } - (void)testRecoverFails { @@ -92,6 +94,7 @@ - (void)testRecoverFails { }]; [realtime connect]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; } @end diff --git a/Tests/ARTRealtimeResumeTest.m b/Tests/ARTRealtimeResumeTest.m index 24538c789..aa35f4a8c 100644 --- a/Tests/ARTRealtimeResumeTest.m +++ b/Tests/ARTRealtimeResumeTest.m @@ -9,6 +9,7 @@ #import #import +#import "ARTRealtime+TestSuite.h" #import "ARTMessage.h" #import "ARTClientOptions.h" #import "ARTPresenceMessage.h" @@ -79,6 +80,8 @@ - (void)testSimpleDisconnected { [channel attach]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; + [realtime testSuite_waitForConnectionToClose:self]; + [realtime2 testSuite_waitForConnectionToClose:self]; } @end diff --git a/Tests/ARTTestUtil.h b/Tests/ARTTestUtil.h index 3c437d935..b6bcf2d07 100644 --- a/Tests/ARTTestUtil.h +++ b/Tests/ARTTestUtil.h @@ -73,6 +73,8 @@ typedef void (^ARTRealtimeConstructorCb)(ARTRealtime *realtime); + (void)waitForWithTimeout:(NSUInteger *_Nonnull)counter list:(NSArray *)list timeout:(NSTimeInterval)timeout; + (void)delay:(NSTimeInterval)timeout block:(dispatch_block_t)block; ++ (void(^)())splitFulfillFrom:(XCTestCase *)testCase expectation:(XCTestExpectation *)expectation in:(NSInteger)howMany; + @end ART_ASSUME_NONNULL_END diff --git a/Tests/ARTTestUtil.m b/Tests/ARTTestUtil.m index f93388a62..78b7516f1 100644 --- a/Tests/ARTTestUtil.m +++ b/Tests/ARTTestUtil.m @@ -316,4 +316,16 @@ + (ARTClientOptions *)newSandboxApp:(XCTestCase *)testCase withDescription:(cons return options; } ++ (void(^)())splitFulfillFrom:(XCTestCase *)testCase expectation:(XCTestExpectation *)expectation in:(NSInteger)howMany { + __block NSInteger left = howMany; + return ^{ + left--; + if (left == 0) { + [expectation fulfill]; + } else if (left < 0) { + _XCTPrimitiveFail(testCase, @"%s called more than the expected %ld times", __FUNCTION__, (long)howMany); + } + }; +} + @end