From 226f852590035595e8b107e8988f8f7d6ce1da17 Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Thu, 26 Nov 2015 11:59:50 +0000 Subject: [PATCH 1/6] Added ARTConnectionDetails (proxy for tests) --- ably-ios/ARTConnectionDetails.h | 20 ++++++++++++++++++ ably-ios/ARTConnectionDetails.m | 37 +++++++++++++++++++++++++++++++++ ably-ios/ARTProtocolMessage.h | 2 ++ ably-ios/ARTProtocolMessage.m | 13 ++++++++++++ ably-ios/ably.h | 1 + ably.xcodeproj/project.pbxproj | 8 +++++++ 6 files changed, 81 insertions(+) create mode 100644 ably-ios/ARTConnectionDetails.h create mode 100644 ably-ios/ARTConnectionDetails.m diff --git a/ably-ios/ARTConnectionDetails.h b/ably-ios/ARTConnectionDetails.h new file mode 100644 index 000000000..3b6801de7 --- /dev/null +++ b/ably-ios/ARTConnectionDetails.h @@ -0,0 +1,20 @@ +// +// ARTConnectionDetails.h +// ably +// +// Created by Ricardo Pereira on 26/11/15. +// Copyright © 2015 Ably. All rights reserved. +// + +#import + +@class ARTProtocolMessage; + +@interface ARTConnectionDetails : NSObject + +@property (readonly, getter=getClientId) NSString *clientId; +@property (readonly, getter=getConnectionKey) NSString *connectionKey; + +- (instancetype)initWithProtocolMessage:(ARTProtocolMessage *)protocolMessage; + +@end diff --git a/ably-ios/ARTConnectionDetails.m b/ably-ios/ARTConnectionDetails.m new file mode 100644 index 000000000..0f67525a9 --- /dev/null +++ b/ably-ios/ARTConnectionDetails.m @@ -0,0 +1,37 @@ +// +// ARTConnectionDetails.m +// ably +// +// Created by Ricardo Pereira on 26/11/15. +// Copyright © 2015 Ably. All rights reserved. +// + +#import "ARTConnectionDetails.h" + +#import "ARTProtocolMessage.h" + +@interface ARTConnectionDetails () { + // FIXME: temporary + __weak ARTProtocolMessage* _protocolMessage; +} + +@end + +@implementation ARTConnectionDetails + +- (instancetype)initWithProtocolMessage:(ARTProtocolMessage *)protocolMessage { + if (self == [super init]) { + _protocolMessage = protocolMessage; + } + return self; +} + +- (NSString *)getClientId { + return _protocolMessage.clientId; +} + +- (NSString *)getConnectionKey { + return _protocolMessage.connectionKey; +} + +@end diff --git a/ably-ios/ARTProtocolMessage.h b/ably-ios/ARTProtocolMessage.h index 35cb8734b..09ec88f7d 100644 --- a/ably-ios/ARTProtocolMessage.h +++ b/ably-ios/ARTProtocolMessage.h @@ -9,6 +9,7 @@ #import #import "CompatibilityMacros.h" +@class ARTConnectionDetails; @class ARTErrorInfo; typedef NS_ENUM(NSUInteger, ARTProtocolMessageAction) { @@ -57,6 +58,7 @@ ART_ASSUME_NONNULL_BEGIN @property (art_nullable, readwrite, strong, nonatomic) NSArray *presence; @property (readonly, assign, nonatomic) BOOL ackRequired; @property (readwrite, assign, nonatomic) int64_t flags; +@property (readonly, getter=connectionDetails) ARTConnectionDetails *connectionDetails; - (BOOL)isSyncEnabled; diff --git a/ably-ios/ARTProtocolMessage.m b/ably-ios/ARTProtocolMessage.m index cb4f37d74..32e7d0ce0 100644 --- a/ably-ios/ARTProtocolMessage.m +++ b/ably-ios/ARTProtocolMessage.m @@ -8,6 +8,14 @@ #import "ARTProtocolMessage.h" #import "ARTStatus.h" +#import "ARTConnectionDetails.h" + +@interface ARTProtocolMessage () { + // FIXME: temporary + ARTConnectionDetails *_connectionDetails; +} + +@end @implementation ARTProtocolMessage @@ -29,6 +37,7 @@ - (id)init { _presence = nil; _flags = 0; _error = nil; + _connectionDetails = [[ARTConnectionDetails alloc] initWithProtocolMessage:self]; } return self; } @@ -63,4 +72,8 @@ - (BOOL)isSyncEnabled { return self.flags & 0x1; } +- (ARTConnectionDetails *)getConnectionDetails { + return _connectionDetails; +} + @end diff --git a/ably-ios/ably.h b/ably-ios/ably.h index c3b91cc00..2b526a368 100644 --- a/ably-ios/ably.h +++ b/ably-ios/ably.h @@ -19,6 +19,7 @@ FOUNDATION_EXPORT const unsigned char ablyVersionString[]; #import #import +#import #import #import #import diff --git a/ably.xcodeproj/project.pbxproj b/ably.xcodeproj/project.pbxproj index 601eb152e..18a0066d2 100644 --- a/ably.xcodeproj/project.pbxproj +++ b/ably.xcodeproj/project.pbxproj @@ -125,6 +125,8 @@ D746AE541BBD85C5003ECEF8 /* ARTChannelCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = D746AE521BBD85C5003ECEF8 /* ARTChannelCollection.m */; }; D7588AF31BFF91B800BB8279 /* ARTURLSessionServerTrust.h in Headers */ = {isa = PBXBuildFile; fileRef = D7588AF11BFF91B800BB8279 /* ARTURLSessionServerTrust.h */; settings = {ASSET_TAGS = (); }; }; D7588AF41BFF91B800BB8279 /* ARTURLSessionServerTrust.m in Sources */ = {isa = PBXBuildFile; fileRef = D7588AF21BFF91B800BB8279 /* ARTURLSessionServerTrust.m */; settings = {ASSET_TAGS = (); }; }; + 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 */; settings = {ASSET_TAGS = (); }; }; D7C1B8771BBEA81A0087B55F /* Auth.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C1B8761BBEA81A0087B55F /* Auth.swift */; }; D7C1B8791BBF5F810087B55F /* ARTAuth+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D7C1B8781BBF5F460087B55F /* ARTAuth+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; D7D29B421BE3DEB300374295 /* ARTConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = D7D29B411BE3DEB300374295 /* ARTConnection.m */; settings = {ASSET_TAGS = (); }; }; @@ -316,6 +318,8 @@ D746AE551BBD8622003ECEF8 /* ARTChannelCollection+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ARTChannelCollection+Private.h"; sourceTree = ""; }; D7588AF11BFF91B800BB8279 /* ARTURLSessionServerTrust.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTURLSessionServerTrust.h; sourceTree = ""; }; D7588AF21BFF91B800BB8279 /* ARTURLSessionServerTrust.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTURLSessionServerTrust.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 = ""; }; D7C1B8781BBF5F460087B55F /* ARTAuth+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ARTAuth+Private.h"; sourceTree = ""; }; D7D29B401BE3DD0600374295 /* ARTConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ARTConnection.h; sourceTree = ""; }; @@ -530,6 +534,8 @@ D746AE3B1BBC5AE1003ECEF8 /* ARTRealtimeChannel.m */, D7D29B401BE3DD0600374295 /* ARTConnection.h */, D7D29B411BE3DEB300374295 /* ARTConnection.m */, + D7B17EE11C07208B00A6958E /* ARTConnectionDetails.h */, + D7B17EE21C07208B00A6958E /* ARTConnectionDetails.m */, D7F1D3751BF4DE72001A4B5E /* ARTRealtimePresence.h */, D7F1D3761BF4DE72001A4B5E /* ARTRealtimePresence.m */, D746AE321BBC29EB003ECEF8 /* Transport */, @@ -695,6 +701,7 @@ D746AE431BBC5CD0003ECEF8 /* ARTRealtimeChannel+Private.h in Headers */, D746AE251BBB611C003ECEF8 /* ARTChannel+Private.h in Headers */, D7F1D3731BF4DE07001A4B5E /* ARTRestPresence.h in Headers */, + D7B17EE31C07208B00A6958E /* ARTConnectionDetails.h in Headers */, 1C8065051AE7C8FA00D49357 /* ARTPayload+Private.h in Headers */, 960D07971A46FFC300ED8C8C /* ARTRest+Private.h in Headers */, 1C05CF201AC1D7EB00687AC9 /* ARTRealtime+Private.h in Headers */, @@ -959,6 +966,7 @@ 960D07941A45F1D800ED8C8C /* ARTCrypto.m in Sources */, D7D8F8221BC2BE16009718F2 /* ARTAuthOptions.m in Sources */, 1C55427D1B148306003068DB /* ARTStatus.m in Sources */, + D7B17EE41C07208B00A6958E /* ARTConnectionDetails.m in Sources */, 96BF61591A35B52C004CF2B3 /* ARTHttp.m in Sources */, 1C578E201B3435CA00EF46EC /* ARTFallback.m in Sources */, 96A507B61A37881C0077CDF8 /* ARTNSDate+ARTUtil.m in Sources */, From 211715616ee750b5e7c1e8fa20d624f3fcbddd4b Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Thu, 26 Nov 2015 12:03:24 +0000 Subject: [PATCH 2/6] MockTransport.lastSentMessage --- ablySpec/TestUtilities.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ablySpec/TestUtilities.swift b/ablySpec/TestUtilities.swift index 9eb91cf77..879feba7e 100644 --- a/ablySpec/TestUtilities.swift +++ b/ablySpec/TestUtilities.swift @@ -327,6 +327,7 @@ class MockHTTPExecutor: NSObject, ARTHTTPExecutor { class MockTransport: ARTWebSocketTransport { var lastUrl: NSURL? + var lastSentMessage: ARTProtocolMessage? override func setupWebSocket(params: [NSURLQueryItem], withOptions options: ARTClientOptions) -> NSURL { let url = super.setupWebSocket(params, withOptions: options) @@ -334,4 +335,9 @@ class MockTransport: ARTWebSocketTransport { return url } + override func send(msg: ARTProtocolMessage) { + lastSentMessage = msg + super.send(msg) + } + } From e79e0979a8a3ee3e40eca169ec4305662fcd156d Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Thu, 26 Nov 2015 12:20:14 +0000 Subject: [PATCH 3/6] MockTransport.lastReceivedMessage --- ably-ios/ARTRealtimeTransport.h | 1 + ably-ios/ARTWebSocketTransport.m | 6 +++++- ablySpec/TestUtilities.swift | 6 ++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ably-ios/ARTRealtimeTransport.h b/ably-ios/ARTRealtimeTransport.h index b5353c097..5af00328d 100644 --- a/ably-ios/ARTRealtimeTransport.h +++ b/ably-ios/ARTRealtimeTransport.h @@ -36,6 +36,7 @@ ART_ASSUME_NONNULL_BEGIN @property (readwrite, weak, nonatomic) id delegate; - (void)send:(ARTProtocolMessage *)msg; +- (void)receive:(ARTProtocolMessage *)msg; - (void)connect; - (void)sendClose; - (void)sendPing; diff --git a/ably-ios/ARTWebSocketTransport.m b/ably-ios/ARTWebSocketTransport.m index 84cc18443..bbd6b0e2d 100644 --- a/ably-ios/ARTWebSocketTransport.m +++ b/ably-ios/ARTWebSocketTransport.m @@ -80,6 +80,10 @@ - (void)send:(ARTProtocolMessage *)msg { [self.websocket send:data]; } +- (void)receive:(ARTProtocolMessage *)msg { + [self.delegate realtimeTransport:self didReceiveMessage:msg]; +} + - (void)connect { [self.logger debug:@"ARTWebSocketTransport: websocket connect"]; if ([self.options isBasicAuth]) { @@ -209,7 +213,7 @@ - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message { ARTWebSocketTransport *s = weakSelf; if (s) { ARTProtocolMessage *pm = [s.encoder decodeProtocolMessage:data]; - [s.delegate realtimeTransport:s didReceiveMessage:pm]; + [s receive:pm]; } }); CFRunLoopWakeUp(self.rl); diff --git a/ablySpec/TestUtilities.swift b/ablySpec/TestUtilities.swift index 879feba7e..d5b9b5df2 100644 --- a/ablySpec/TestUtilities.swift +++ b/ablySpec/TestUtilities.swift @@ -328,6 +328,7 @@ class MockTransport: ARTWebSocketTransport { var lastUrl: NSURL? var lastSentMessage: ARTProtocolMessage? + var lastReceivedMessage: ARTProtocolMessage? override func setupWebSocket(params: [NSURLQueryItem], withOptions options: ARTClientOptions) -> NSURL { let url = super.setupWebSocket(params, withOptions: options) @@ -340,4 +341,9 @@ class MockTransport: ARTWebSocketTransport { super.send(msg) } + override func receive(msg: ARTProtocolMessage) { + lastReceivedMessage = msg + super.receive(msg) + } + } From bf5b72fccb0fce6f6098ce827145698ac50b2f9e Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Thu, 26 Nov 2015 14:28:21 +0000 Subject: [PATCH 4/6] =?UTF-8?q?RSA15a=20=E2=9C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ablySpec/Auth.swift | 80 +++++++++++++++++++++++++----------- ablySpec/TestUtilities.swift | 6 ++- 2 files changed, 60 insertions(+), 26 deletions(-) diff --git a/ablySpec/Auth.swift b/ablySpec/Auth.swift index d0258f6ad..9f48a00bf 100644 --- a/ablySpec/Auth.swift +++ b/ablySpec/Auth.swift @@ -177,34 +177,66 @@ class Auth : QuickSpec { // RSA15 context("token auth and clientId") { // RSA15a - it("should check clientId consistency") { - let expectedClientId = "client_string" - let options = AblyTests.setupOptions(AblyTests.jsonRestOptions) - options.clientId = expectedClientId - - let client = ARTRest(options: options) - client.httpExecutor = mockExecutor - - waitUntil(timeout: 10) { done in - // Token - client.calculateAuthorization(ARTAuthMethod.Token) { token, error in - if let e = error { - XCTFail(e.description) + context("should check clientId consistency") { + + it("on rest") { + let expectedClientId = "client_string" + let options = AblyTests.setupOptions(AblyTests.jsonRestOptions) + options.clientId = expectedClientId + + let client = ARTRest(options: options) + client.httpExecutor = mockExecutor + + waitUntil(timeout: 10) { done in + // Token + client.calculateAuthorization(ARTAuthMethod.Token) { token, error in + if let e = error { + XCTFail(e.description) + } + expect(client.auth.clientId).to(equal(expectedClientId)) + done() } - expect(client.auth.clientId).to(equal(expectedClientId)) - done() + } + + switch extractBodyAsJSON(mockExecutor.requests.first) { + case .Failure(let error): + XCTFail(error) + case .Success(let httpBody): + guard let requestedClientId = httpBody.unbox["clientId"] as? String else { XCTFail("No clientId field in HTTPBody"); return } + expect(requestedClientId).to(equal(expectedClientId)) } } - - switch extractBodyAsJSON(mockExecutor.requests.first) { - case .Failure(let error): - XCTFail(error) - case .Success(let httpBody): - guard let requestedClientId = httpBody.unbox["clientId"] as? String else { XCTFail("No clientId field in HTTPBody"); return } - expect(requestedClientId).to(equal(expectedClientId)) + + it("on realtime") { + let expectedClientId = "client_string" + let options = AblyTests.setupOptions(AblyTests.jsonRestOptions) + options.clientId = expectedClientId + options.autoConnect = false + + let client = ARTRealtime(options: options) + client.setTransportClass(MockTransport.self) + client.connect() + + waitUntil(timeout: testTimeout) { done in + client.eventEmitter.on({ state, error in + if state == .Connected && error == nil { + let currentChannel = client.channel("test") + currentChannel.subscribe({ message, errorInfo in + done() + }) + currentChannel.publish("ping", cb:nil) + } + }) + } + + if let transport = client.transport as? MockTransport, let connectionDetails = transport.connectedMessage?.connectionDetails { + // CONNECTED ProtocolMessage + expect(connectionDetails.clientId).to(equal(expectedClientId)) + } + else { + XCTFail("MockTransport is not working") + } } - - // TODO: Realtime.connectionDetails of the CONNECTED ProtocolMessage } // RSA15b diff --git a/ablySpec/TestUtilities.swift b/ablySpec/TestUtilities.swift index d5b9b5df2..87e280d01 100644 --- a/ablySpec/TestUtilities.swift +++ b/ablySpec/TestUtilities.swift @@ -328,7 +328,7 @@ class MockTransport: ARTWebSocketTransport { var lastUrl: NSURL? var lastSentMessage: ARTProtocolMessage? - var lastReceivedMessage: ARTProtocolMessage? + var connectedMessage: ARTProtocolMessage? override func setupWebSocket(params: [NSURLQueryItem], withOptions options: ARTClientOptions) -> NSURL { let url = super.setupWebSocket(params, withOptions: options) @@ -342,7 +342,9 @@ class MockTransport: ARTWebSocketTransport { } override func receive(msg: ARTProtocolMessage) { - lastReceivedMessage = msg + if msg.action == .Connected { + connectedMessage = msg + } super.receive(msg) } From 4c756a9f8b0ddea88adaecaba360a2d438befaec Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Mon, 28 Dec 2015 16:14:13 +0000 Subject: [PATCH 5/6] Test: using a wildcard for clientId (verify exception) --- ablySpec/Auth.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ablySpec/Auth.swift b/ablySpec/Auth.swift index 9f48a00bf..eab2b0622 100644 --- a/ablySpec/Auth.swift +++ b/ablySpec/Auth.swift @@ -237,6 +237,13 @@ class Auth : QuickSpec { XCTFail("MockTransport is not working") } } + + it("with wildcard") { + let options = AblyTests.setupOptions(AblyTests.jsonRestOptions) + options.clientId = "*" + expect{ ARTRest(options: options) }.to(raiseException()) + expect{ ARTRealtime(options: options) }.to(raiseException()) + } } // RSA15b From 786b56b4654d1df87ed0a4388cc06858547f2eb6 Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Mon, 28 Dec 2015 19:05:31 +0000 Subject: [PATCH 6/6] Close connection --- ablySpec/Auth.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ablySpec/Auth.swift b/ablySpec/Auth.swift index eab2b0622..a05737590 100644 --- a/ablySpec/Auth.swift +++ b/ablySpec/Auth.swift @@ -214,6 +214,9 @@ class Auth : QuickSpec { options.autoConnect = false let client = ARTRealtime(options: options) + defer { + client.close() + } client.setTransportClass(MockTransport.self) client.connect()