Skip to content

Commit

Permalink
Merge pull request #37 from haitaoli/master
Browse files Browse the repository at this point in the history
Support multiple requests for the same url
  • Loading branch information
dstnbrkr authored Jun 30, 2017
2 parents 055417f + 3f8a115 commit 0cc83fa
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 12 deletions.
2 changes: 2 additions & 0 deletions VCRURLConnection/VCRCassette.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@
- (void)addRecording:(VCRRecording *)recording;

- (VCRRecording *)recordingForRequestKey:(VCRRequestKey *)request;
- (VCRRecording *)recordingForRequestKey:(VCRRequestKey *)request replaying:(BOOL)replaying;

- (VCRRecording *)recordingForRequest:(NSURLRequest *)request;
- (VCRRecording *)recordingForRequest:(NSURLRequest *)request replaying:(BOOL)replaying;

- (NSArray *)allKeys;

Expand Down
41 changes: 34 additions & 7 deletions VCRURLConnection/VCRCassette.m
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,30 @@ - (id)initWithData:(NSData *)data {
- (void)addRecording:(VCRRecording *)recording {
if (recording.URI) {
VCRRequestKey *key = [VCRRequestKey keyForObject:recording];
[self.responseDictionary setObject:recording forKey:key];
NSMutableArray * recordings = [self.responseDictionary objectForKey:key];

if (recordings == NULL) {
recordings = [[NSMutableArray alloc] init];
[self.responseDictionary setObject:recordings forKey:key];
}

[recordings addObject:recording];
} else {
[self.regexRecordings addObject:recording];
}
}

- (VCRRecording *)recordingForRequestKey:(VCRRequestKey *)key {
__block VCRRecording *recording = [self.responseDictionary objectForKey:key];
- (VCRRecording *)recordingForRequestKey:(VCRRequestKey *)key replaying:(BOOL)replaying {
__block VCRRecording *recording;
NSMutableArray *recordings = [self.responseDictionary objectForKey:key];

if (recordings != NULL && recordings.count > 0) {
recording = [recordings objectAtIndex:0];

if (recordings.count > 1 && replaying) {
[recordings removeObjectAtIndex:0];
}
}

if (!recording) {
[self.regexRecordings enumerateObjectsUsingBlock:^(VCRRecording *obj, NSUInteger idx, BOOL *stop) {
Expand All @@ -88,16 +104,27 @@ - (VCRRecording *)recordingForRequestKey:(VCRRequestKey *)key {
return recording;
}

- (VCRRecording *)recordingForRequest:(NSURLRequest *)request {
- (VCRRecording *)recordingForRequestKey:(VCRRequestKey *)key {
return [self recordingForRequestKey:key replaying:NO];
}

- (VCRRecording *)recordingForRequest:(NSURLRequest *)request replaying:(BOOL)replaying {
VCRRequestKey *key = [VCRRequestKey keyForObject:request];
return [self recordingForRequestKey:key];
return [self recordingForRequestKey:key replaying:replaying];
}

- (VCRRecording *)recordingForRequest:(NSURLRequest *)request {
return [self recordingForRequest:request replaying:NO];
}

- (id)JSON {
NSMutableArray *recordings = [NSMutableArray array];
for (VCRRecording *recording in self.responseDictionary.allValues) {
[recordings addObject:[recording JSON]];
for (NSArray *requestRecordings in self.responseDictionary.allValues) {
for (VCRRecording *recording in requestRecordings) {
[recordings addObject:[recording JSON]];
}
}

for (VCRRecording *recording in self.regexRecordings) {
[recordings addObject:[recording JSON]];
}
Expand Down
8 changes: 4 additions & 4 deletions VCRURLConnection/VCRReplayingURLProtocol.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,20 @@
@implementation VCRReplayingURLProtocol

+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
return [VCR isReplaying] && [self recordingForRequest:request] && ([request.URL.scheme isEqualToString:@"https"] || [request.URL.scheme isEqualToString:@"http"]);
return [VCR isReplaying] && [self recordingForRequest:request replaying:NO] && ([request.URL.scheme isEqualToString:@"https"] || [request.URL.scheme isEqualToString:@"http"]);
}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
return request;
}

+ (VCRRecording *)recordingForRequest:(NSURLRequest *)request {
+ (VCRRecording *)recordingForRequest:(NSURLRequest *)request replaying:(BOOL)replaying {
VCRCassette *cassette = [[VCRCassetteManager defaultManager] currentCassette];
return [cassette recordingForRequest:request];
return [cassette recordingForRequest:request replaying:replaying];
}

- (void)startLoading {
VCRRecording *recording = [[self class] recordingForRequest:self.request];
VCRRecording *recording = [[self class] recordingForRequest:self.request replaying:YES];
NSError *error = recording.error;
if (!error) {
NSURL *url = [NSURL URLWithString:recording.URI];
Expand Down
76 changes: 75 additions & 1 deletion VCRURLConnectionTests/VCR_NSURLSessionTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ - (void)setUp
}

- (void)testResponseIsRecordedWithSession:(NSURLSession *)session {
[VCR setRecording:YES];
[VCR setReplaying:NO];

NSURL *url = [NSURL URLWithString:@"http://www.iana.org/domains/reserved"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
__block BOOL completed = NO;
Expand Down Expand Up @@ -80,6 +83,7 @@ - (void)testResponseIsRecordedForSharedSession {
- (void)testResponseIsRecordedForDefaultSession {
[self testResponseIsRecordedWithSession:self.defaultSession];
}

/*
- (void)testResponseIsRecordedForEphemeralSession {
[self testResponseIsRecordedWithSession:self.ephemeralSession];
Expand All @@ -89,12 +93,15 @@ - (void)testResponseIsRecordedForEphemeralSession {
// FIXME: need bundle id to test background session

- (void)testResponseIsReplayedWithSession:(NSURLSession *)session {
[VCR setReplaying:YES];
[VCR setRecording:NO];

NSString *uri = @"http://foo";
id json = @{ @"method": @"GET", @"uri": uri, @"body": @"Foo Bar Baz" };
VCRCassette *cassette = [[VCRCassette alloc] initWithJSON:@[ json ]];
[[VCRCassetteManager defaultManager] setCurrentCassette:cassette];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:uri]];
VCRRecording *recording = [[[VCRCassetteManager defaultManager] currentCassette] recordingForRequest:request];
VCRRecording *recording = [[[VCRCassetteManager defaultManager] currentCassette] recordingForRequest:request replaying:YES];

__block BOOL completed = NO;
__block NSData *receivedData;
Expand All @@ -114,6 +121,65 @@ - (void)testResponseIsReplayedWithSession:(NSURLSession *)session {
XCTAssertEqualObjects(receivedData, recording.data, @"");
}

- (void)testMultipleResponsesAreReplayedWithSession:(NSURLSession *)session {
[VCR setReplaying:YES];
[VCR setRecording:NO];

NSString *uri = @"http://foo";
id json1 = @{ @"method": @"GET", @"uri": uri, @"body": @"body 1" };
id json2 = @{ @"method": @"GET", @"uri": uri, @"body": @"body 2" };

VCRCassette *cassette = [[VCRCassette alloc] initWithJSON:@[ json1, json2 ]];
[[VCRCassetteManager defaultManager] setCurrentCassette:cassette];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:uri]];

__block BOOL completed = NO;
__block NSString *receivedData;
__block NSHTTPURLResponse *httpResponse;
XCTestExpectation *expectation;
NSURLSessionDataTask *task;

expectation = [self expectationWithDescription:@""];
task = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
completed = YES;
receivedData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
httpResponse = (NSHTTPURLResponse *)response;
[expectation fulfill];
}];
[task resume];

[self waitForExpectationsWithTimeout:60 handler:nil];
XCTAssertEqualObjects(receivedData, @"body 1", @"");

expectation = [self expectationWithDescription:@""];
task = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
completed = YES;
receivedData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
httpResponse = (NSHTTPURLResponse *)response;
[expectation fulfill];
}];
[task resume];

[self waitForExpectationsWithTimeout:60 handler:nil];
XCTAssertEqualObjects(receivedData, @"body 2", @"");

// The last recording is reused
expectation = [self expectationWithDescription:@""];
task = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
completed = YES;
receivedData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
httpResponse = (NSHTTPURLResponse *)response;
[expectation fulfill];
}];
[task resume];

[self waitForExpectationsWithTimeout:60 handler:nil];
XCTAssertEqualObjects(receivedData, @"body 2", @"");
}

- (void)testResponseIsReplayedForSharedSession {
[self testResponseIsReplayedWithSession:self.sharedSession];
}
Expand All @@ -122,6 +188,14 @@ - (void)testResponseIsReplayedForDefaultSession {
[self testResponseIsReplayedWithSession:self.defaultSession];
}

- (void)testMultipleResponsesAreReplayedForSharedSession {
[self testMultipleResponsesAreReplayedWithSession:self.sharedSession];
}

- (void)testMultipleResponsesAreReplayedForDefaultSession {
[self testMultipleResponsesAreReplayedWithSession:self.defaultSession];
}

/*
- (void)testResponseIsReplayedForEphemeralSession {
[self testResponseIsReplayedWithSession:self.ephemeralSession];
Expand Down

0 comments on commit 0cc83fa

Please sign in to comment.