From 0948e0bdef6002febcd28244ea3772870e0c567f Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Fri, 13 Nov 2015 20:09:38 +0000 Subject: [PATCH 1/4] Optional debug info --- ably-iosTests/ARTRealtimeAttachTest.m | 7 +------ ably-iosTests/ARTTestUtil.h | 2 ++ ably-iosTests/ARTTestUtil.m | 22 +++++++++++++++++----- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/ably-iosTests/ARTRealtimeAttachTest.m b/ably-iosTests/ARTRealtimeAttachTest.m index fcbac2344..4c77d3f73 100644 --- a/ably-iosTests/ARTRealtimeAttachTest.m +++ b/ably-iosTests/ARTRealtimeAttachTest.m @@ -346,12 +346,7 @@ - (void)testChannelClosesOnClose { - (void)testPresenceEnterRestricted { XCTestExpectation *expect = [self expectationWithDescription:@"testSimpleDisconnected"]; - // Debug - ARTClientOptions *clientOptions = [ARTTestUtil clientOptions]; - clientOptions.logLevel = ARTLogLevelVerbose; - - // FIXME: why is `setupApp` using a callback? hard reading... could be a blocking method (only once per test) - [ARTTestUtil setupApp:clientOptions withAlteration:TestAlterationRestrictCapability cb:^(ARTClientOptions *options) { + [ARTTestUtil setupApp:[ARTTestUtil clientOptions] withDebug:YES withAlteration:TestAlterationRestrictCapability cb:^(ARTClientOptions *options) { // Connection options.clientId = @"some_client_id"; ARTRealtime *realtime = [[ARTRealtime alloc] initWithOptions:options]; diff --git a/ably-iosTests/ARTTestUtil.h b/ably-iosTests/ARTTestUtil.h index 91e96abc8..abebbf645 100644 --- a/ably-iosTests/ARTTestUtil.h +++ b/ably-iosTests/ARTTestUtil.h @@ -29,8 +29,10 @@ typedef NS_ENUM(NSUInteger, TestAlteration) { + (ARTCipherPayloadEncoder *)getTestCipherEncoder; +// FIXME: why is `setupApp` using a callback? hard reading... could be a blocking method (only once per test) + (void)setupApp:(ARTClientOptions *)options cb:(void(^)(ARTClientOptions *options))cb; + (void)setupApp:(ARTClientOptions *)options withAlteration:(TestAlteration) alt cb:(void (^)(ARTClientOptions *))cb; ++ (void)setupApp:(ARTClientOptions *)options withDebug:(BOOL)debug withAlteration:(TestAlteration) alt cb:(void (^)(ARTClientOptions *))cb; + (float)timeout; + (ARTClientOptions *)clientOptions; diff --git a/ably-iosTests/ARTTestUtil.m b/ably-iosTests/ARTTestUtil.m index 11b384209..ec2aecfc9 100644 --- a/ably-iosTests/ARTTestUtil.m +++ b/ably-iosTests/ARTTestUtil.m @@ -44,7 +44,7 @@ + (NSString *)getCrypto128Json { return [ARTTestUtil getFileByName:@"ably-common/test-resources/crypto-data-128.json"]; } -+ (void)setupApp:(ARTClientOptions *)options withAlteration:(TestAlteration)alt appId:(NSString *)appId cb:(void (^)(ARTClientOptions *))cb { ++ (void)setupApp:(ARTClientOptions *)options withDebug:(BOOL)debug withAlteration:(TestAlteration)alt appId:(NSString *)appId cb:(void (^)(ARTClientOptions *))cb { NSString *str = [ARTTestUtil getTestAppSetupJson]; if (str == nil) { [NSException raise:@"error getting test-app-setup.json loaded. Maybe ably-common is missing" format:@""]; @@ -62,6 +62,9 @@ + (void)setupApp:(ARTClientOptions *)options withAlteration:(TestAlteration)alt options.environment = @"sandbox"; } options.binary = NO; + if (debug) { + options.logLevel = ARTLogLevelVerbose; + } NSString *urlStr = [NSString stringWithFormat:@"https://%@:%d/apps", options.restHost, options.restPort]; NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStr]]; @@ -71,8 +74,10 @@ + (void)setupApp:(ARTClientOptions *)options withAlteration:(TestAlteration)alt [req setValue:@"application/json" forHTTPHeaderField:@"Accept"]; [req setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; - // NSLog(@"Creating test app. URL: %@, Method: %@, Body: %@, Headers: %@", req.URL, req.HTTPMethod, [[NSString alloc] initWithData:req.HTTPBody encoding:NSUTF8StringEncoding], req.allHTTPHeaderFields); - + if (debug) { + NSLog(@"Creating test app. URL: %@, Method: %@, Body: %@, Headers: %@", req.URL, req.HTTPMethod, [[NSString alloc] initWithData:req.HTTPBody encoding:NSUTF8StringEncoding], req.allHTTPHeaderFields); + } + CFRunLoopRef rl = CFRunLoopGetCurrent(); NSURLSession *urlSession = [NSURLSession sharedSession]; @@ -92,6 +97,9 @@ + (void)setupApp:(ARTClientOptions *)options withAlteration:(TestAlteration)alt NSLog(@"No response"); return; } + else if (debug) { + NSLog(@"Response: %@", json); + } NSDictionary *key = json[@"keys"][(alt == TestAlterationRestrictCapability ? 1 :0)]; @@ -112,8 +120,12 @@ + (void)setupApp:(ARTClientOptions *)options withAlteration:(TestAlteration)alt [task resume]; } -+ (void)setupApp:(ARTClientOptions *)options withAlteration:(TestAlteration) alt cb:(void (^)(ARTClientOptions *))cb { - [ARTTestUtil setupApp:options withAlteration:alt appId:nil cb:cb]; ++ (void)setupApp:(ARTClientOptions *)options withDebug:(BOOL)debug withAlteration:(TestAlteration)alt cb:(void (^)(ARTClientOptions *))cb { + [ARTTestUtil setupApp:options withDebug:debug withAlteration:alt appId:nil cb:cb]; +} + ++ (void)setupApp:(ARTClientOptions *)options withAlteration:(TestAlteration)alt cb:(void (^)(ARTClientOptions *))cb { + [ARTTestUtil setupApp:options withDebug:NO withAlteration:alt cb:cb]; } + (void)setupApp:(ARTClientOptions *)options cb:(void (^)(ARTClientOptions *))cb { From 9ec244a26c587712b3e1d5c0fafeb267ce926a5a Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Fri, 13 Nov 2015 20:46:27 +0000 Subject: [PATCH 2/4] realtimeTransportFailed: missing error information --- ably-ios/ARTRealtime.m | 7 +++---- ably-ios/ARTRealtimeTransport.h | 7 ++++++- ably-ios/ARTStatus.h | 4 +++- ably-ios/ARTStatus.m | 10 +++++++++- ably-ios/ARTWebSocketTransport.m | 8 ++++---- ably-iosTests/ARTRealtimeAttachTest.m | 4 ++++ 6 files changed, 29 insertions(+), 11 deletions(-) diff --git a/ably-ios/ARTRealtime.m b/ably-ios/ARTRealtime.m index bc1984ce6..4c1392a05 100644 --- a/ably-ios/ARTRealtime.m +++ b/ably-ios/ARTRealtime.m @@ -789,7 +789,7 @@ - (void)realtimeTransportUnavailable:(id)transport { } - (void)realtimeTransportClosed:(id)transport { - //Close succeeded. Nothing more to do. + // Close succeeded. Nothing more to do. [self transition:ARTRealtimeClosed]; } @@ -797,9 +797,8 @@ - (void)realtimeTransportDisconnected:(id)transport { [self transition:ARTRealtimeDisconnected]; } -- (void)realtimeTransportFailed:(id)transport { - // TODO add error codes to these failed transitions - [self transition:ARTRealtimeFailed]; +- (void)realtimeTransportFailed:(id)transport withErrorInfo:(ARTErrorInfo *)errorInfo { + [self transition:ARTRealtimeFailed withErrorInfo:errorInfo]; } - (void)realtimeTransportNeverConnected:(id)transport { diff --git a/ably-ios/ARTRealtimeTransport.h b/ably-ios/ARTRealtimeTransport.h index ff3655a78..b5353c097 100644 --- a/ably-ios/ARTRealtimeTransport.h +++ b/ably-ios/ARTRealtimeTransport.h @@ -12,6 +12,9 @@ @class ARTProtocolMessage; @class ARTStatus; +@class ARTErrorInfo; + +ART_ASSUME_NONNULL_BEGIN @protocol ARTRealtimeTransportDelegate @@ -25,7 +28,7 @@ - (void)realtimeTransportNeverConnected:(id)transport; - (void)realtimeTransportRefused:(id)transport; - (void)realtimeTransportTooBig:(id)transport; -- (void)realtimeTransportFailed:(id)transport; +- (void)realtimeTransportFailed:(id)transport withErrorInfo:(ARTErrorInfo *)errorInfo; @end @@ -40,3 +43,5 @@ - (void)abort:(ARTStatus *)reason; @end + +ART_ASSUME_NONNULL_END diff --git a/ably-ios/ARTStatus.h b/ably-ios/ARTStatus.h index 87de10256..27fd62cf5 100644 --- a/ably-ios/ARTStatus.h +++ b/ably-ios/ARTStatus.h @@ -29,18 +29,20 @@ ART_ASSUME_NONNULL_BEGIN FOUNDATION_EXPORT NSString *const ARTAblyErrorDomain; -// FIXME: base NSError @interface ARTErrorInfo : NSObject @property (readonly, copy, nonatomic) NSString *message; @property (readonly, assign, nonatomic) int statusCode; @property (readonly, assign, nonatomic) int code; +// FIXME: use NSInteger instead int (don't know what kind of processor architecture your code might run) - (ARTErrorInfo *)setCode:(int) code message:(NSString *) message; - (ARTErrorInfo *)setCode:(int) code status:(int) status message:(NSString *) message; + (ARTErrorInfo *)createWithCode:(int)code message:(NSString *)message; + (ARTErrorInfo *)createWithCode:(int)code status:(int)status message:(NSString *)message; +// FIXME: base NSError ++ (ARTErrorInfo *)createWithNSError:(NSError *)error; - (NSString *)description; diff --git a/ably-ios/ARTStatus.m b/ably-ios/ARTStatus.m index 2025eec7c..b9074c9e0 100644 --- a/ably-ios/ARTStatus.m +++ b/ably-ios/ARTStatus.m @@ -12,11 +12,15 @@ NSString *const ARTAblyErrorDomain = @"ARTAblyErrorDomain"; +NSInteger getStatusFromCode(NSInteger code) { + return code / 100; +} + @implementation ARTErrorInfo - (ARTErrorInfo *)setCode:(int)code message:(NSString *)message { _code = code; - _statusCode = code / 100; + _statusCode = getStatusFromCode(code); _message = message; return self; } @@ -36,6 +40,10 @@ + (ARTErrorInfo *)createWithCode:(int)code status:(int)status message:(NSString return [[[ARTErrorInfo alloc] init] setCode:code status:status message:message]; } ++ (ARTErrorInfo *)createWithNSError:(NSError *)error { + return [[[ARTErrorInfo alloc] init] setCode:error.code status:getStatusFromCode(error.code) message:error.description]; +} + - (NSString *)description { return [NSString stringWithFormat:@"ARTErrorInfo with code %d, message: %@", self.statusCode, self.message]; } diff --git a/ably-ios/ARTWebSocketTransport.m b/ably-ios/ARTWebSocketTransport.m index 452c4b45f..b2a75bde2 100644 --- a/ably-ios/ARTWebSocketTransport.m +++ b/ably-ios/ARTWebSocketTransport.m @@ -17,6 +17,7 @@ #import "ARTClientOptions.h" #import "ARTAuthTokenParams.h" #import "ARTAuthTokenDetails.h" +#import "ARTStatus.h" enum { ARTWsNeverConnected = -1, @@ -97,7 +98,7 @@ - (void)connect { if (error) { [selfStrong.logger error:@"ARTWebSocketTransport: token auth failed with %@", error.description]; - [selfStrong.delegate realtimeTransportFailed:selfStrong]; + [selfStrong.delegate realtimeTransportFailed:selfStrong withErrorInfo:[ARTErrorInfo createWithNSError:error]]; return; } @@ -229,7 +230,7 @@ - (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error { CFRunLoopPerformBlock(self.rl, kCFRunLoopDefaultMode, ^{ ARTWebSocketTransport *s = weakSelf; if (s) { - [s.delegate realtimeTransportFailed:s]; + [s.delegate realtimeTransportFailed:s withErrorInfo:[ARTErrorInfo createWithNSError:error]]; } }); CFRunLoopWakeUp(self.rl); @@ -284,8 +285,7 @@ - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reas default: { // Failed - // no idea why - [s.delegate realtimeTransportFailed:s]; + [s.delegate realtimeTransportFailed:s withErrorInfo:[ARTErrorInfo createWithCode:code message:reason]]; break; } } diff --git a/ably-iosTests/ARTRealtimeAttachTest.m b/ably-iosTests/ARTRealtimeAttachTest.m index 4c77d3f73..2f4a64f10 100644 --- a/ably-iosTests/ARTRealtimeAttachTest.m +++ b/ably-iosTests/ARTRealtimeAttachTest.m @@ -359,6 +359,10 @@ - (void)testPresenceEnterRestricted { [expect fulfill]; }]; } + else if (state == ARTRealtimeFailed && errorInfo) { + XCTFail(@"%@", errorInfo); + [expect fulfill]; + } }]; }]; [self waitForExpectationsWithTimeout:[ARTTestUtil timeout] handler:nil]; From 9cec8f1251c80ef7095e046247e7a694dccce118 Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Sat, 14 Nov 2015 00:53:55 +0000 Subject: [PATCH 3/4] TODO: Assign on requestToken - Key does not support requested capabilities --- ably-iosTests/ARTRealtimeAttachTest.m | 9 +++++++-- ably-iosTests/ARTTestUtil.m | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ably-iosTests/ARTRealtimeAttachTest.m b/ably-iosTests/ARTRealtimeAttachTest.m index 2f4a64f10..1308dbcc8 100644 --- a/ably-iosTests/ARTRealtimeAttachTest.m +++ b/ably-iosTests/ARTRealtimeAttachTest.m @@ -359,8 +359,13 @@ - (void)testPresenceEnterRestricted { [expect fulfill]; }]; } - else if (state == ARTRealtimeFailed && errorInfo) { - XCTFail(@"%@", errorInfo); + else if (state == ARTRealtimeFailed) { + if (errorInfo) { + XCTFail(@"%@", errorInfo); + } + else { + XCTFail(); + } [expect fulfill]; } }]; diff --git a/ably-iosTests/ARTTestUtil.m b/ably-iosTests/ARTTestUtil.m index ec2aecfc9..95f3435c1 100644 --- a/ably-iosTests/ARTTestUtil.m +++ b/ably-iosTests/ARTTestUtil.m @@ -105,6 +105,8 @@ + (void)setupApp:(ARTClientOptions *)options withDebug:(BOOL)debug withAlteratio ARTClientOptions *testOptions = [options copy]; + // TODO: assign key[@"capability"] + testOptions.key = key[@"keyStr"]; if (alt == TestAlterationBadKeyId || alt == TestAlterationBadKeyValue) From cfd9668b1600d9941c16457e26c49332eaf6badd Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Mon, 16 Nov 2015 15:15:13 +0000 Subject: [PATCH 4/4] Fixed: testPresenceEnterRestricted (forced capability) --- ably-iosTests/ARTRealtimeAttachTest.m | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/ably-iosTests/ARTRealtimeAttachTest.m b/ably-iosTests/ARTRealtimeAttachTest.m index 1308dbcc8..b0cebc6de 100644 --- a/ably-iosTests/ARTRealtimeAttachTest.m +++ b/ably-iosTests/ARTRealtimeAttachTest.m @@ -16,6 +16,9 @@ #import "ARTLog.h" #import "ARTEventEmitter.h" #import "ARTStatus.h" +#import "ARTAuth.h" +#import "ARTAuthTokenParams.h" +#import "ARTAuthTokenDetails.h" @interface ARTRealtimeAttachTest : XCTestCase { ARTRealtime *_realtime; @@ -346,11 +349,22 @@ - (void)testChannelClosesOnClose { - (void)testPresenceEnterRestricted { XCTestExpectation *expect = [self expectationWithDescription:@"testSimpleDisconnected"]; - [ARTTestUtil setupApp:[ARTTestUtil clientOptions] withDebug:YES withAlteration:TestAlterationRestrictCapability cb:^(ARTClientOptions *options) { + [ARTTestUtil setupApp:[ARTTestUtil clientOptions] withAlteration:TestAlterationRestrictCapability cb:^(ARTClientOptions *options) { // Connection options.clientId = @"some_client_id"; + options.autoConnect = false; + ARTRealtime *realtime = [[ARTRealtime alloc] initWithOptions:options]; + // FIXME: there is setupApp, testRealtime, testRest, ... try to unify them and then use this code + ARTAuthTokenParams *tokenParams = [[ARTAuthTokenParams alloc] initWithClientId:options.clientId]; + tokenParams.capability = @"{\"canpublish:*\":[\"publish\"],\"canpublish:andpresence\":[\"presence\",\"publish\"],\"cansubscribe:*\":[\"subscribe\"]}"; + + [realtime.auth authorise:tokenParams options:options force:false callback:^(ARTAuthTokenDetails *tokenDetails, NSError *error) { + options.token = tokenDetails.token; + [realtime connect]; + }]; + [realtime.eventEmitter on:^(ARTRealtimeConnectionState state, ARTErrorInfo *errorInfo) { if (state == ARTRealtimeConnected) { ARTRealtimeChannel *channel = [realtime channel:@"some_unpermitted_channel"];