Skip to content

Commit

Permalink
Added mechanism for closing all requests, executed when server is sto…
Browse files Browse the repository at this point in the history
…pped.

Improves testing in isolation.  There will be no outstanding requests
to negatively impact testing.

Also addresses an issue where a bad .tail.defaults.json file would
result in the request being dequeued but not terminated.
  • Loading branch information
bnickel committed Aug 9, 2013
1 parent 7ce3ae9 commit cf7405f
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 13 deletions.
36 changes: 35 additions & 1 deletion AMYServer Tests/AMYServerTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,29 +46,62 @@ - (void)testSuccess
[tester tapViewWithAccessibilityLabel:@"Close"];
}


- (void)testThatRequestsCloseWithAnErrorStatus
{
[exampleServer closeAllRequests];
[tester waitForViewWithAccessibilityLabel:@"500 status code"];
[tester tapViewWithAccessibilityLabel:@"Close"];
}

- (void)testThatClosingAllRequestsClosesAllRequests
{
[exampleServer closeAllRequests];
KIFExpectFailure([[exampleServer usingTimeout:0.5] waitForLoginWithUsername:@"brian" password:@"$ecret" andRespondWithSuccess:YES message:@"Welcome, Brian" token:@"12345"]);
[tester tapViewWithAccessibilityLabel:@"Close"];
}

- (void)testThatStoppingTheServerClosesAllRequests
{
[exampleServer stop];
[exampleServer start];
KIFExpectFailure([[exampleServer usingTimeout:0.5] waitForLoginWithUsername:@"brian" password:@"$ecret" andRespondWithSuccess:YES message:@"Welcome, Brian" token:@"12345"]);
[tester tapViewWithAccessibilityLabel:@"Close"];
}

- (void)testMissingMocktail
{
KIFExpectFailure([exampleServer waitForRequestMatchingMocktail:@"logon" andRespondWithValues:@{}]);
[exampleServer closeAllRequests];
[tester tapViewWithAccessibilityLabel:@"Close"];
}

- (void)testMocktailWithBadMustache
{
KIFExpectFailure([exampleServer waitForRequestMatchingMocktail:@"bad-mustache" andRespondWithValues:@{@"message": @"hello"}]);
[exampleServer closeAllRequests];
[tester tapViewWithAccessibilityLabel:@"Close"];
}

- (void)testMocktailWithNotEnoughLines
{
KIFExpectFailure([exampleServer waitForRequestMatchingMocktail:@"not-enough-lines" andRespondWithValues:@{@"message": @"hello"}]);
[exampleServer closeAllRequests];
[tester tapViewWithAccessibilityLabel:@"Close"];
}

- (void)testMocktailWithBadJSON
{
KIFExpectFailure([exampleServer waitForRequestMatchingMocktail:@"bad-json" andRespondWithValues:@{@"message": @"hello"}]);
[exampleServer closeAllRequests];
[tester tapViewWithAccessibilityLabel:@"Close"];
}

- (void)testMocktailWithInvalidHeader
{
KIFExpectFailure([exampleServer waitForRequestMatchingMocktail:@"invalid-header" andRespondWithValues:@{@"message": @"hello"}]);
[exampleServer closeAllRequests];
[tester tapViewWithAccessibilityLabel:@"Close"];
}

- (void)testBasicMocktail
Expand Down Expand Up @@ -107,7 +140,8 @@ - (void)testMocktailWithFailingBodyConditions
KIFTestWaitCondition([json[@"username"] isEqualToString:@"joe"], error, @"Could not find username");
return KIFTestStepResultSuccess;
} andRespondWithValues:@{}]);
[exampleServer closeAllRequests];
[tester tapViewWithAccessibilityLabel:@"Close"];
}


@end
1 change: 1 addition & 0 deletions AMYServer/AMYServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@

- (void)start;
- (void)stop;
- (void)closeAllRequests;

@end
26 changes: 16 additions & 10 deletions AMYServer/AMYServer.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,15 @@ - (void)start

- (void)stop
{
[self closeAllRequests];
[_AMYURLProtocol stopMonitoringURL:self.baseURL];
}

- (void)closeAllRequests
{
[_AMYURLProtocol closeAllRequestsWithBaseURL:self.baseURL];
}

- (AMYRequest *)waitForRequestMatchingBlock:(KIFTestStepResult (^)(NSURLRequest *, NSError **))block
{
__block AMYRequest *request = nil;
Expand Down Expand Up @@ -67,6 +73,16 @@ - (void)waitForRequestMatchingMocktail:(NSString *)mocktail withHTTPBodyMatching
[self failWithError:[NSError KIFErrorWithUnderlyingError:error format:@"Failed to load mocktail: %@", error.localizedDescription] stopTest:YES];
}

NSDictionary *headers = [response headersWithValues:values error:&error];
if (error) {
[self failWithError:[NSError KIFErrorWithUnderlyingError:error format:@"Failed to generate headers: %@", error.localizedDescription] stopTest:YES];
}

NSData *body = [response bodyWithValues:values error:&error];
if (error) {
[self failWithError:[NSError KIFErrorWithUnderlyingError:error format:@"Failed to generate body: %@", error.localizedDescription] stopTest:YES];
}

AMYRequest *request = [self waitForRequestMatchingBlock:^KIFTestStepResult(NSURLRequest *request, NSError *__autoreleasing *error) {

KIFTestWaitCondition([response matchesURL:request.URL method:request.HTTPMethod patternLength:NULL], error, @"Could not find request matching mocktail.");
Expand All @@ -78,16 +94,6 @@ - (void)waitForRequestMatchingMocktail:(NSString *)mocktail withHTTPBodyMatching
return KIFTestStepResultSuccess;
}];

NSDictionary *headers = [response headersWithValues:values error:&error];
if (error) {
[self failWithError:[NSError KIFErrorWithUnderlyingError:error format:@"Failed to generate headers: %@", error.localizedDescription] stopTest:YES];
}

NSData *body = [response bodyWithValues:values error:&error];
if (error) {
[self failWithError:[NSError KIFErrorWithUnderlyingError:error format:@"Failed to generate body: %@", error.localizedDescription] stopTest:YES];
}

[request respondWithStatusCode:response.statusCode headerFields:headers];
[request sendData:body];
[request close];
Expand Down
1 change: 1 addition & 0 deletions AMYServer/_AMYURLProtocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
+ (AMYRequest *)findAndRemoveRequestMatchingBaseURL:(NSURL *)baseURL block:(KIFTestStepResult (^)(NSURLRequest *URLRequest, NSError **error))block error:(NSError **)error;
+ (void)startMonitoringURL:(NSURL *)URL;
+ (void)stopMonitoringURL:(NSURL *)URL;
+ (void)closeAllRequestsWithBaseURL:(NSURL *)URL;
+ (NSArray *)pendingURLRequestsMatchingBaseURL:(NSURL *)baseURL;

@end
17 changes: 16 additions & 1 deletion AMYServer/_AMYURLProtocol.m
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,16 @@ + (void)addRequestForProtocol:(_AMYURLProtocol *)protocol
[[self pendingRequests] addObject:protocol];
}

+ (AMYRequest *)findAndRemoveAnyRequestMatchingBaseURL:(NSURL *)baseURL
{
return [self findAndRemoveRequestMatchingBaseURL:baseURL block:nil error:NULL];
}

+ (AMYRequest *)findAndRemoveRequestMatchingBaseURL:(NSURL *)baseURL block:(KIFTestStepResult (^)(NSURLRequest *URLRequest, NSError **error))block error:(NSError **)error
{
AMYAssertMainThread();
for (_AMYURLProtocol *protocol in [self pendingRequests]) {
if ([baseURL isEqual:[self baseURLForRequest:protocol.request]] && protocol.canRespond && block(protocol.request, error) == KIFTestStepResultSuccess) {
if ([baseURL isEqual:[self baseURLForRequest:protocol.request]] && protocol.canRespond && (!block || block(protocol.request, error) == KIFTestStepResultSuccess)) {

AMYRequest *request = [[AMYRequest alloc] initWithProtocol:protocol];
[[self pendingRequests] removeObject:protocol];
Expand Down Expand Up @@ -119,6 +124,16 @@ + (void)stopMonitoringURL:(NSURL *)URL
}
}

+ (void)closeAllRequestsWithBaseURL:(NSURL *)URL
{
AMYAssertMainThread();
AMYRequest *request;
while ((request = [self findAndRemoveAnyRequestMatchingBaseURL:URL])) {
[request respondWithStatusCode:500 headerFields:nil];
[request close];
}
}

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
return [self baseURLForRequest:request] != nil;
Expand Down
6 changes: 5 additions & 1 deletion Test Host/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ - (IBAction)logIn {

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

NSLog(@"Headers: %@", [(NSHTTPURLResponse *)response allHeaderFields]);
NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
if (HTTPResponse.statusCode != 200) {
[[[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"%d status code", HTTPResponse.statusCode] message:nil delegate:nil cancelButtonTitle:@"Close" otherButtonTitles:nil] show];
return;
}

NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];

Expand Down

0 comments on commit cf7405f

Please sign in to comment.