refine validation logic

This commit is contained in:
Stephan Diederich 2013-08-15 22:30:39 +02:00
parent 4647907ea0
commit ff555cb87d
4 changed files with 177 additions and 82 deletions

View File

@ -46,6 +46,15 @@ typedef void(^tValidationCompletion)(BOOL validated, NSError *error);
@property (nonatomic, weak) id<BITAuthenticatorDelegate> delegate; @property (nonatomic, weak) id<BITAuthenticatorDelegate> delegate;
/**
The authentication token from HockeyApp.
Set the token to the `Secret ID` which HockeyApp provides for every app.
When running the app from the App Store, this setting is ignored.
*/
@property (nonatomic, copy) NSString *authenticationSecret;
#pragma mark - Identification #pragma mark - Identification
/** /**
* Provides an identification for the current app installation * Provides an identification for the current app installation
@ -53,7 +62,7 @@ typedef void(^tValidationCompletion)(BOOL validated, NSError *error);
* During Alpha and Beta-phase HockeyApp tries to uniquely identify each app installation * During Alpha and Beta-phase HockeyApp tries to uniquely identify each app installation
* to provide better error reporting & analytics. If authenticator is configured to login * to provide better error reporting & analytics. If authenticator is configured to login
* (@see BITAuthenticatorValidationType), this identifier is retrieved from HockeyApp. In case * (@see BITAuthenticatorValidationType), this identifier is retrieved from HockeyApp. In case
* it is disabled, it returns this the current vendorIdentifier provided by UIKit. * it is disabled, it returns the vendorIdentifier provided by UIKit.
* *
* @return a string identifying this app installation * @return a string identifying this app installation
*/ */
@ -77,8 +86,8 @@ typedef void(^tValidationCompletion)(BOOL validated, NSError *error);
/** /**
* Validate the app installation * Validate the app installation
* *
* Depending on @see loginOption, this is reset after the app becomes active and tries to revalidate * Depending on @see validationType, this is called by the manager after the app becomes active
* the installation. * and tries to revalidate the installation.
* You should not need to call this, as it's done automatically once the manager has * You should not need to call this, as it's done automatically once the manager has
* been started, depending on validationType. * been started, depending on validationType.
* *

View File

@ -40,15 +40,17 @@ static NSString* const kBITAuthenticatorLastAuthenticatedVersionKey = @"BITAuthe
switch (self.validationType) { switch (self.validationType) {
case BITAuthenticatorValidationTypeOnAppActive: case BITAuthenticatorValidationTypeOnAppActive:
[self validateInstallationWithCompletion:nil]; [self validateInstallationWithCompletion:[self defaultValidationCompletionBlock]];
break; break;
case BITAuthenticatorValidationTypeOnFirstLaunch: case BITAuthenticatorValidationTypeOnFirstLaunch:
if(![self.lastAuthenticatedVersion isEqualToString:self.executableUUID]) { if(![self.lastAuthenticatedVersion isEqualToString:self.executableUUID]) {
[self validateInstallationWithCompletion:nil]; [self validateInstallationWithCompletion:[self defaultValidationCompletionBlock]];
} }
break; break;
case BITAuthenticatorValidationTypeNever:
case BITAuthenticatorValidationTypeOptional: case BITAuthenticatorValidationTypeOptional:
//TODO: what to do in optional case?
break;
case BITAuthenticatorValidationTypeNever:
break; break;
} }
} }
@ -99,9 +101,10 @@ static NSString* const kBITAuthenticatorLastAuthenticatedVersionKey = @"BITAuthe
} }
}]; }];
} else { } else {
NSString *validationEndpoint = @"validate"; NSString *validationPath = [NSString stringWithFormat:@"api/3/apps/%@/identity/validate", self.encodedAppIdentifier];
__weak typeof (self) weakSelf = self; __weak typeof (self) weakSelf = self;
[self getPath:validationEndpoint [self getPath:validationPath
parameters:[self validationParameters]
completion:^(BITHTTPOperation *operation, id response, NSError *error) { completion:^(BITHTTPOperation *operation, id response, NSError *error) {
typeof (self) strongSelf = weakSelf; typeof (self) strongSelf = weakSelf;
if(nil == response) { if(nil == response) {
@ -112,20 +115,34 @@ static NSString* const kBITAuthenticatorLastAuthenticatedVersionKey = @"BITAuthe
NSError *error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain NSError *error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorNetworkError code:BITAuthenticatorNetworkError
userInfo:userInfo]; userInfo:userInfo];
[strongSelf validationFailedWithError:error]; [strongSelf validationFailedWithError:error completion:completion];
} else { } else {
NSError *validationParseError = nil; NSError *validationParseError = nil;
BOOL isValidated = [strongSelf.class isValidationResponseValid:response error:&validationParseError]; BOOL isValidated = [strongSelf.class isValidationResponseValid:response error:&validationParseError];
if(isValidated) { if(isValidated) {
[strongSelf validationSucceeded]; [strongSelf validationSucceededWithCompletion:completion];
} else { } else {
[strongSelf validationFailedWithError:validationParseError]; [strongSelf validationFailedWithError:validationParseError completion:completion];
} }
} }
}]; }];
} }
} }
- (NSDictionary*) validationParameters {
NSParameterAssert(self.authenticationToken);
NSDictionary *params = nil;
switch (self.authenticationType) {
case BITAuthenticatorAuthTypeEmail:
params = @{@"iuid" : self.authenticationToken};
break;
case BITAuthenticatorAuthTypeEmailAndPassword:
params = @{@"auid" : self.authenticationToken};
break;
}
return params;
}
+ (BOOL) isValidationResponseValid:(id) response error:(NSError **) error { + (BOOL) isValidationResponseValid:(id) response error:(NSError **) error {
NSParameterAssert(response); NSParameterAssert(response);
@ -150,8 +167,31 @@ static NSString* const kBITAuthenticatorLastAuthenticatedVersionKey = @"BITAuthe
return NO; return NO;
} }
//TODO: add proper validation NSString *status = jsonObject[@"status"];
return [jsonObject[@"isValid"] boolValue]; if([status isEqualToString:@"not authorized"]) {
if(error) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorNotAuthorized
userInfo:nil];
}
return NO;
} else if([status isEqualToString:@"not found"]) {
if(error) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorNotAuthorized
userInfo:nil];
}
return NO;
} else if([status isEqualToString:@"validated"]) {
return YES;
} else {
if(error) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorAPIServerReturnedInvalidRespone
userInfo:nil];
}
return NO;
}
} }
- (void)authenticateWithCompletion:(tAuthenticationCompletion)completion { - (void)authenticateWithCompletion:(tAuthenticationCompletion)completion {
@ -160,27 +200,39 @@ static NSString* const kBITAuthenticatorLastAuthenticatedVersionKey = @"BITAuthe
return; return;
} }
BITAuthenticationViewController *viewController = [[BITAuthenticationViewController alloc] initWithStyle:UITableViewStyleGrouped]; BOOL requiresPassword;
viewController.delegate = self;
viewController.authenticator = self;
switch (self.authenticationType) { switch (self.authenticationType) {
case BITAuthenticatorAuthTypeEmailAndPassword: case BITAuthenticatorAuthTypeEmailAndPassword:
viewController.requirePassword = YES; requiresPassword = YES;
break; break;
case BITAuthenticatorAuthTypeEmail: case BITAuthenticatorAuthTypeEmail:
viewController.requirePassword = NO; requiresPassword = NO;
break; break;
} }
if(viewController) { BITAuthenticationViewController *viewController = [[BITAuthenticationViewController alloc] initWithApplicationIdentifier:self.encodedAppIdentifier
[self.delegate authenticator:self willShowAuthenticationController:viewController]; requirePassword:requiresPassword
_authenticationController = viewController; delegate:self];
_authenticationCompletionBlock = completion; viewController.authenticator = self;
UIViewController *rootViewController = [self.findVisibleWindow rootViewController]; switch (self.validationType) {
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController]; case BITAuthenticatorValidationTypeNever:
[rootViewController presentModalViewController:navController case BITAuthenticatorValidationTypeOptional:
animated:YES]; viewController.showsCancelButton = YES;
break;
case BITAuthenticatorValidationTypeOnAppActive:
case BITAuthenticatorValidationTypeOnFirstLaunch:
viewController.showsCancelButton = NO;
break;
} }
[self.delegate authenticator:self willShowAuthenticationController:viewController];
_authenticationController = viewController;
_authenticationCompletionBlock = completion;
UIViewController *rootViewController = [self.findVisibleWindow rootViewController];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
[rootViewController presentModalViewController:navController
animated:YES];
} }
#pragma mark - AuthenticationViewControllerDelegate #pragma mark - AuthenticationViewControllerDelegate
@ -202,8 +254,10 @@ static NSString* const kBITAuthenticatorLastAuthenticatedVersionKey = @"BITAuthe
- (void) authenticationViewController:(UIViewController*) viewController - (void) authenticationViewController:(UIViewController*) viewController
authenticatedWithToken:(NSString*) token { authenticatedWithToken:(NSString*) token {
[viewController dismissModalViewControllerAnimated:YES];
_authenticationController = nil; _authenticationController = nil;
self.authenticationToken = token; self.authenticationToken = token;
self.lastAuthenticatedVersion = [self executableUUID];
if(self.authenticationCompletionBlock) { if(self.authenticationCompletionBlock) {
self.authenticationCompletionBlock(self.authenticationToken, nil); self.authenticationCompletionBlock(self.authenticationToken, nil);
self.authenticationCompletionBlock = nil; self.authenticationCompletionBlock = nil;
@ -213,29 +267,17 @@ static NSString* const kBITAuthenticatorLastAuthenticatedVersionKey = @"BITAuthe
} }
#pragma mark - Validation Pseudo-Delegate #pragma mark - Validation Pseudo-Delegate
- (void)validationFailedWithError:(NSError *)validationError { - (void)validationFailedWithError:(NSError *)validationError completion:(tValidationCompletion) completion{
if(self.validationCompletion) { if(completion) {
self.validationCompletion(NO, validationError); completion(NO, validationError);
self.validationCompletion = nil;
} else { } else {
[self.delegate authenticator:self failedToValidateInstallationWithError:validationError]; [self.delegate authenticator:self failedToValidateInstallationWithError:validationError];
} }
switch (self.validationType) {
case BITAuthenticatorValidationTypeNever:
case BITAuthenticatorValidationTypeOptional:
break;
case BITAuthenticatorValidationTypeOnAppActive:
case BITAuthenticatorValidationTypeOnFirstLaunch:
//TODO tell delegate and block the application
break;
}
} }
- (void)validationSucceeded { - (void)validationSucceededWithCompletion:(tValidationCompletion) completion {
if(self.validationCompletion) { if(completion) {
self.validationCompletion(YES, nil); completion(YES, nil);
self.validationCompletion = nil;
} else { } else {
[self.delegate authenticatorDidValidateInstallation:self]; [self.delegate authenticatorDidValidateInstallation:self];
} }
@ -302,10 +344,24 @@ static NSString* const kBITAuthenticatorLastAuthenticatedVersionKey = @"BITAuthe
#pragma mark - Application Lifecycle #pragma mark - Application Lifecycle
- (void)applicationDidBecomeActive:(NSNotification *)note { - (void)applicationDidBecomeActive:(NSNotification *)note {
if(BITAuthenticatorValidationTypeOnAppActive == self.validationType) { if(BITAuthenticatorValidationTypeOnAppActive == self.validationType) {
[self validateInstallationWithCompletion:nil]; [self validateInstallationWithCompletion:[self defaultValidationCompletionBlock]];
} }
} }
- (tValidationCompletion) defaultValidationCompletionBlock {
return ^(BOOL validated, NSError *error) {
switch (self.validationType) {
case BITAuthenticatorValidationTypeNever:
case BITAuthenticatorValidationTypeOptional:
break;
case BITAuthenticatorValidationTypeOnAppActive:
case BITAuthenticatorValidationTypeOnFirstLaunch:
[self authenticateWithCompletion:nil];
break;
}
};
};
#pragma mark - Networking #pragma mark - Networking
- (NSMutableURLRequest *) requestWithMethod:(NSString*) method - (NSMutableURLRequest *) requestWithMethod:(NSString*) method
path:(NSString *) path path:(NSString *) path

View File

@ -30,7 +30,6 @@
@property (nonatomic, copy) NSString *lastAuthenticatedVersion; @property (nonatomic, copy) NSString *lastAuthenticatedVersion;
@property (nonatomic, copy) tAuthenticationCompletion authenticationCompletionBlock; @property (nonatomic, copy) tAuthenticationCompletion authenticationCompletionBlock;
@property (nonatomic, copy) tValidationCompletion validationCompletion;
/** /**
* removes all previously stored authentication tokens, UDIDs, etc * removes all previously stored authentication tokens, UDIDs, etc
@ -44,8 +43,8 @@
- (void) applicationDidBecomeActive:(NSNotification*) note; - (void) applicationDidBecomeActive:(NSNotification*) note;
#pragma mark - Validation callbacks #pragma mark - Validation callbacks
- (void) validationSucceeded; - (void) validationSucceededWithCompletion:(tValidationCompletion) completion;
- (void) validationFailedWithError:(NSError *) validationError; - (void) validationFailedWithError:(NSError *) validationError completion:(tValidationCompletion) completion;
#pragma mark - Networking helpers (TODO: move to base-class / networking component) #pragma mark - Networking helpers (TODO: move to base-class / networking component)

View File

@ -41,6 +41,7 @@
} }
- (void)tearDown { - (void)tearDown {
[_sut cancelOperationsWithPath:nil method:nil];
[_sut cleanupInternalStorage]; [_sut cleanupInternalStorage];
_sut = nil; _sut = nil;
@ -201,16 +202,6 @@
[verify(delegateMock) authenticator:_sut willShowAuthenticationController:(id)anything()]; [verify(delegateMock) authenticator:_sut willShowAuthenticationController:(id)anything()];
} }
- (void) testThatValidationFailsWithoutAnURL {
id delegateMock = mockProtocol(@protocol(BITAuthenticatorDelegate));
_sut.delegate = delegateMock;
_sut.authenticationToken = @"Test";
[_sut validateInstallationWithCompletion:nil];
[verify(delegateMock) authenticator:_sut failedToValidateInstallationWithError:(id)anything()];
}
#pragma mark - Lifetime checks #pragma mark - Lifetime checks
- (void) testThatValidationDoesntTriggerIfDisabled { - (void) testThatValidationDoesntTriggerIfDisabled {
id delegateMock = mockProtocol(@protocol(BITAuthenticatorDelegate)); id delegateMock = mockProtocol(@protocol(BITAuthenticatorDelegate));
@ -270,7 +261,7 @@
_sut.validationType = BITAuthenticatorValidationTypeOnFirstLaunch; _sut.validationType = BITAuthenticatorValidationTypeOnFirstLaunch;
[_sut validateInstallationWithCompletion:nil]; [_sut validateInstallationWithCompletion:nil];
[_sut validationFailedWithError:nil]; [_sut validationFailedWithError:nil completion:nil];
[verifyCount(delegateMock, times(1)) authenticator:_sut failedToValidateInstallationWithError:(id)anything()]; [verifyCount(delegateMock, times(1)) authenticator:_sut failedToValidateInstallationWithError:(id)anything()];
[verifyCount(delegateMock, never()) authenticatorDidValidateInstallation:_sut]; [verifyCount(delegateMock, never()) authenticatorDidValidateInstallation:_sut];
@ -282,7 +273,7 @@
_sut.validationType = BITAuthenticatorValidationTypeOnFirstLaunch; _sut.validationType = BITAuthenticatorValidationTypeOnFirstLaunch;
[_sut validateInstallationWithCompletion:nil]; [_sut validateInstallationWithCompletion:nil];
[_sut validationSucceeded]; [_sut validationSucceededWithCompletion:nil];
[verifyCount(delegateMock, never()) authenticator:_sut failedToValidateInstallationWithError:(id)anything()]; [verifyCount(delegateMock, never()) authenticator:_sut failedToValidateInstallationWithError:(id)anything()];
[verifyCount(delegateMock, times(1)) authenticatorDidValidateInstallation:_sut]; [verifyCount(delegateMock, times(1)) authenticatorDidValidateInstallation:_sut];
@ -291,37 +282,75 @@
#pragma mark - Networking base tests #pragma mark - Networking base tests
- (void) testThatURLRequestHasBaseURLSet { - (void) testThatURLRequestHasBaseURLSet {
_sut.serverURL = @"http://myserver.com"; _sut.serverURL = @"http://myserver.com";
NSMutableURLRequest *request = [_sut requestWithMethod:@"GET" path:nil]; NSMutableURLRequest *request = [_sut requestWithMethod:@"GET" path:nil parameters:nil];
assertThat(request.URL, equalTo([NSURL URLWithString:@"http://myserver.com/"])); assertThat(request.URL, equalTo([NSURL URLWithString:@"http://myserver.com/"]));
} }
- (void) testThatURLRequestHasPathAppended { - (void) testThatURLRequestHasPathAppended {
_sut.serverURL = @"http://myserver.com"; _sut.serverURL = @"http://myserver.com";
NSMutableURLRequest *request = [_sut requestWithMethod:@"GET" path:@"projects"]; NSMutableURLRequest *request = [_sut requestWithMethod:@"GET" path:@"projects" parameters:nil];
assertThat(request.URL, equalTo([NSURL URLWithString:@"http://myserver.com/projects"])); assertThat(request.URL, equalTo([NSURL URLWithString:@"http://myserver.com/projects"]));
} }
- (void) testThatURLRequestHasMethodSet { - (void) testThatURLRequestHasMethodSet {
NSMutableURLRequest *request = [_sut requestWithMethod:@"POST" path:nil]; NSMutableURLRequest *request = [_sut requestWithMethod:@"POST" path:nil parameters:nil];
assertThat(request.HTTPMethod, equalTo(@"POST")); assertThat(request.HTTPMethod, equalTo(@"POST"));
} }
- (void) testThatOperationHasURLRequestSet { - (void) testThatOperationHasURLRequestSet {
_sut.serverURL = @"http://myserver.com"; _sut.serverURL = @"http://myserver.com";
NSURLRequest *r = [_sut requestWithMethod:@"PUT" path:@"x"]; NSURLRequest *r = [_sut requestWithMethod:@"PUT" path:@"x" parameters:nil];
BITHTTPOperation *op = [_sut operationWithURLRequest:r BITHTTPOperation *op = [_sut operationWithURLRequest:r
completion:nil]; completion:nil];
assertThat(op.URLRequest, equalTo(r)); assertThat(op.URLRequest, equalTo(r));
} }
- (void) testThatURLRequestHasParametersInGetAppended {
NSDictionary *parameters = @{
@"email" : @"peter@pan.de",
@"push" : @"pop",
};
NSMutableURLRequest *request = [_sut requestWithMethod:@"GET"
path:@"something"
parameters:parameters];
NSURL *url = request.URL;
NSString *params = [url query];
NSArray *paramPairs = [params componentsSeparatedByString:@"&"];
assertThat(paramPairs, hasCountOf(2));
NSMutableDictionary *dict = [NSMutableDictionary new];
for(NSString *paramPair in paramPairs) {
NSArray *a = [paramPair componentsSeparatedByString:@"="];
assertThat(a, hasCountOf(2));
dict[a[0]] = a[1];
}
assertThat(dict, equalTo(parameters));
}
- (void) testThatURLRequestHasParametersInPostInTheBody {
//pending
}
#pragma mark - Convenience methods #pragma mark - Convenience methods
- (void) testThatGetPathCreatesAndEnquesAnOperation { - (void) testThatGetPathCreatesAndEnquesAnOperation {
assertThatUnsignedInt(_sut.operationQueue.operationCount, equalToUnsignedInt(0)); assertThatUnsignedInt(_sut.operationQueue.operationCount, equalToUnsignedInt(0));
[given([_sut operationWithURLRequest:(id)anything() [given([_sut operationWithURLRequest:(id)anything()
completion:(id)anything()]) willReturn:[NSOperation new]]; completion:nil]) willReturn:[NSOperation new]];
[_sut getPath:@"endpoint" [_sut getPath:@"endpoint"
parameters:nil
completion:nil];
assertThatUnsignedInt(_sut.operationQueue.operationCount, equalToUnsignedInt(1));
}
- (void) testThatPostPathCreatesAndEnquesAnOperation {
assertThatUnsignedInt(_sut.operationQueue.operationCount, equalToUnsignedInt(0));
[given([_sut operationWithURLRequest:nil
completion:nil]) willReturn:[NSOperation new]];
[_sut postPath:@"endpoint"
parameters:nil
completion:nil]; completion:nil];
assertThatUnsignedInt(_sut.operationQueue.operationCount, equalToUnsignedInt(1)); assertThatUnsignedInt(_sut.operationQueue.operationCount, equalToUnsignedInt(1));
} }
@ -343,9 +372,9 @@
- (void) testThatOperationCancellingMatchesAllOperationsWithNilMethod { - (void) testThatOperationCancellingMatchesAllOperationsWithNilMethod {
[_sut.operationQueue setSuspended:YES]; [_sut.operationQueue setSuspended:YES];
NSURLRequest *requestGet = [_sut requestWithMethod:@"GET" path:nil]; NSURLRequest *requestGet = [_sut requestWithMethod:@"GET" path:nil parameters:nil];
NSURLRequest *requestPut = [_sut requestWithMethod:@"PUT" path:nil]; NSURLRequest *requestPut = [_sut requestWithMethod:@"PUT" path:nil parameters:nil];
NSURLRequest *requestPost = [_sut requestWithMethod:@"POST" path:nil]; NSURLRequest *requestPost = [_sut requestWithMethod:@"POST" path:nil parameters:nil];
[_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestGet [_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestGet
completion:nil]]; completion:nil]];
[_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestPut [_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestPut
@ -359,9 +388,9 @@
- (void) testThatOperationCancellingMatchesAllOperationsWithNilPath { - (void) testThatOperationCancellingMatchesAllOperationsWithNilPath {
[_sut.operationQueue setSuspended:YES]; [_sut.operationQueue setSuspended:YES];
NSURLRequest *requestGet = [_sut requestWithMethod:@"GET" path:@"test"]; NSURLRequest *requestGet = [_sut requestWithMethod:@"GET" path:@"test" parameters:nil];
NSURLRequest *requestPut = [_sut requestWithMethod:@"PUT" path:@"Another/acas"]; NSURLRequest *requestPut = [_sut requestWithMethod:@"PUT" path:@"Another/acas" parameters:nil];
NSURLRequest *requestPost = [_sut requestWithMethod:@"POST" path:nil]; NSURLRequest *requestPost = [_sut requestWithMethod:@"POST" path:nil parameters:nil];
[_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestGet [_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestGet
completion:nil]]; completion:nil]];
[_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestPut [_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestPut
@ -375,9 +404,11 @@
- (void) testThatOperationCancellingMatchesAllOperationsWithSetPath { - (void) testThatOperationCancellingMatchesAllOperationsWithSetPath {
NSURLRequest *requestGet = [_sut requestWithMethod:@"GET" path:@"test"]; NSURLRequest *requestGet = [_sut requestWithMethod:@"GET" path:@"test" parameters:nil];
NSURLRequest *requestPut = [_sut requestWithMethod:@"PUT" path:@"Another/acas"]; NSURLRequest *requestPut = [_sut requestWithMethod:@"PUT" path:@"Another/acas" parameters:nil];
NSURLRequest *requestPost = [_sut requestWithMethod:@"POST" path:nil]; NSURLRequest *requestPost = [_sut requestWithMethod:@"POST" path:nil parameters:nil];
[_sut.operationQueue setSuspended:YES];
[_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestGet [_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestGet
completion:nil]]; completion:nil]];
[_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestPut [_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestPut
@ -385,14 +416,14 @@
[_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestPost [_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestPost
completion:nil]]; completion:nil]];
assertThatUnsignedInt(_sut.operationQueue.operationCount, equalToUnsignedInt(3)); assertThatUnsignedInt(_sut.operationQueue.operationCount, equalToUnsignedInt(3));
[_sut cancelOperationsWithPath:@"Another/acas" method:nil]; NSUInteger numCancelled = [_sut cancelOperationsWithPath:@"Another/acas" method:nil];
assertThatUnsignedInt(_sut.operationQueue.operationCount, equalToUnsignedInt(2)); assertThatUnsignedInt(numCancelled, equalToUnsignedInt(1));
} }
- (void) testThatOperationCancellingMatchesAllOperationsWithSetMethod { - (void) testThatOperationCancellingMatchesAllOperationsWithSetMethod {
NSURLRequest *requestGet = [_sut requestWithMethod:@"GET" path:@"test"]; NSURLRequest *requestGet = [_sut requestWithMethod:@"GET" path:@"test" parameters:nil];
NSURLRequest *requestPut = [_sut requestWithMethod:@"PUT" path:@"Another/acas"]; NSURLRequest *requestPut = [_sut requestWithMethod:@"PUT" path:@"Another/acas" parameters:nil];
NSURLRequest *requestPost = [_sut requestWithMethod:@"POST" path:nil]; NSURLRequest *requestPost = [_sut requestWithMethod:@"POST" path:nil parameters:nil];
[_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestGet [_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestGet
completion:nil]]; completion:nil]];
[_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestPut [_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestPut
@ -405,9 +436,9 @@
} }
- (void) testThatOperationCancellingMatchesAllOperationsWithSetMethodAndPath { - (void) testThatOperationCancellingMatchesAllOperationsWithSetMethodAndPath {
NSURLRequest *requestGet = [_sut requestWithMethod:@"GET" path:@"test"]; NSURLRequest *requestGet = [_sut requestWithMethod:@"GET" path:@"test" parameters:nil];
NSURLRequest *requestPut = [_sut requestWithMethod:@"PUT" path:@"Another/acas"]; NSURLRequest *requestPut = [_sut requestWithMethod:@"PUT" path:@"Another/acas" parameters:nil];
NSURLRequest *requestPost = [_sut requestWithMethod:@"POST" path:nil]; NSURLRequest *requestPost = [_sut requestWithMethod:@"POST" path:nil parameters:nil];
[_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestGet [_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestGet
completion:nil]]; completion:nil]];
[_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestPut [_sut enqeueHTTPOperation:[_sut operationWithURLRequest:requestPut