mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-01-12 22:51:50 +08:00
Improve RKPathMatcher so that it only evaluates a path match positively if the number of slashes in the source string matches the number of slashes in the pattern. closes #1212, closes #1192
This commit is contained in:
@@ -139,7 +139,7 @@
|
||||
@property (nonatomic, strong, readonly) NSDictionary *responseMappingsDictionary;
|
||||
|
||||
/**
|
||||
Returns an array containing all `RKResponseDescriptor` objects in the configured `responseDescriptors` array that were found to match response.
|
||||
Returns an array containing all `RKResponseDescriptor` objects in the configured `responseDescriptors` array that were found to match the response.
|
||||
|
||||
@see `responseDescriptors`
|
||||
@see `RKResponseDescriptor`
|
||||
|
||||
@@ -38,6 +38,16 @@ static NSString *RKEncodeURLString(NSString *unencodedString)
|
||||
return encodedString;
|
||||
}
|
||||
|
||||
static NSUInteger RKNumberOfSlashesInString(NSString *string)
|
||||
{
|
||||
static NSRegularExpression *regex = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
regex = [NSRegularExpression regularExpressionWithPattern:@"/" options:NSRegularExpressionCaseInsensitive error:nil];
|
||||
});
|
||||
return [regex numberOfMatchesInString:string options:0 range:NSMakeRange(0, [string length])];
|
||||
}
|
||||
|
||||
@interface RKPathMatcher ()
|
||||
@property (nonatomic, strong) SOCPattern *socPattern;
|
||||
@property (nonatomic, copy) NSString *patternString; // SOCPattern keeps it private
|
||||
@@ -102,14 +112,10 @@ static NSString *RKEncodeURLString(NSString *unencodedString)
|
||||
[argumentsCollection addEntriesFromDictionary:self.queryParameters];
|
||||
}
|
||||
}
|
||||
if (![self matches])
|
||||
return NO;
|
||||
if (!arguments) {
|
||||
return YES;
|
||||
}
|
||||
if (![self matches]) return NO;
|
||||
if (!arguments) return YES;
|
||||
NSDictionary *extracted = [self.socPattern parameterDictionaryFromSourceString:self.rootPath];
|
||||
if (extracted)
|
||||
[argumentsCollection addEntriesFromDictionary:RKDictionaryByReplacingPercentEscapesInEntriesFromDictionary(extracted)];
|
||||
if (extracted) [argumentsCollection addEntriesFromDictionary:RKDictionaryByReplacingPercentEscapesInEntriesFromDictionary(extracted)];
|
||||
*arguments = argumentsCollection;
|
||||
return YES;
|
||||
}
|
||||
@@ -125,7 +131,8 @@ static NSString *RKEncodeURLString(NSString *unencodedString)
|
||||
{
|
||||
self.sourcePath = sourceString;
|
||||
self.rootPath = sourceString;
|
||||
return [self itMatchesAndHasParsedArguments:arguments tokenizeQueryStrings:shouldTokenize];
|
||||
return [self itMatchesAndHasParsedArguments:arguments tokenizeQueryStrings:shouldTokenize]
|
||||
&& RKNumberOfSlashesInString(self.patternString) == RKNumberOfSlashesInString(self.rootPath);
|
||||
}
|
||||
|
||||
- (NSString *)pathFromObject:(id)object addingEscapes:(BOOL)addEscapes interpolatedParameters:(NSDictionary **)interpolatedParameters
|
||||
|
||||
@@ -284,6 +284,28 @@ NSString *RKPathAndQueryStringFromURLRelativeToURL(NSURL *URL, NSURL *baseURL);
|
||||
expect(mapper.responseMappingsDictionary).to.equal(expectedMappingsDictionary);
|
||||
}
|
||||
|
||||
- (void)testThatResponseDescriptorsDoNotMatchTooAggressively
|
||||
{
|
||||
NSURL *responseURL = [NSURL URLWithString:@"http://restkit.org/categories/some-category-name/articles/the-article-name"];
|
||||
NSURLRequest *request = [NSURLRequest requestWithURL:responseURL];
|
||||
NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:responseURL statusCode:200 HTTPVersion:@"1.1" headerFields:@{@"Content-Type": @"application/json"}];
|
||||
NSData *data = [@"{\"some\": \"Data\"}" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSURL *baseURL = [NSURL URLWithString:@"http://restkit.org"];
|
||||
|
||||
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
|
||||
RKResponseDescriptor *responseDescriptor1 = [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:@"/categories" keyPath:nil statusCodes:[NSIndexSet indexSetWithIndex:200]];
|
||||
responseDescriptor1.baseURL = baseURL;
|
||||
RKResponseDescriptor *responseDescriptor2 = [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:@"/categories/:categoryName" keyPath:nil statusCodes:[NSIndexSet indexSetWithIndex:200]];
|
||||
responseDescriptor2.baseURL = baseURL;
|
||||
RKResponseDescriptor *responseDescriptor3 = [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:@"/categories/:categorySlug/articles/:articleSlug" keyPath:nil statusCodes:[NSIndexSet indexSetWithIndex:200]];
|
||||
responseDescriptor3.baseURL = baseURL;
|
||||
|
||||
RKObjectResponseMapperOperation *mapper = [[RKObjectResponseMapperOperation alloc] initWithRequest:request response:response data:data responseDescriptors:@[ responseDescriptor1, responseDescriptor2, responseDescriptor3 ]];
|
||||
[mapper start];
|
||||
expect(mapper.matchingResponseDescriptors).to.haveCountOf(1);
|
||||
expect(mapper.matchingResponseDescriptors).to.equal(@[ responseDescriptor3 ]);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)testThatObjectResponseMapperOperationDoesNotMapWithTargetObjectForUnsuccessfulResponseStatusCode
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
expect(matches).to.equal(NO);
|
||||
|
||||
pathMatcher = [RKPathMatcher pathMatcherWithPattern:@"/api/:version/organizations/:organizationID"];
|
||||
matches = [pathMatcher matchesPath:@"/api/v1/organizations/1234/" tokenizeQueryStrings:NO parsedArguments:nil];
|
||||
matches = [pathMatcher matchesPath:@"/api/v1/organizations/1234" tokenizeQueryStrings:NO parsedArguments:nil];
|
||||
expect(matches).to.equal(YES);
|
||||
}
|
||||
|
||||
@@ -176,4 +176,21 @@
|
||||
expect(match).to.beTruthy();
|
||||
}
|
||||
|
||||
- (void)testThatMatchingPathPatternsDoesNotMatchPathsShorterThanTheInput
|
||||
{
|
||||
NSString *path = @"/categories/some-category-name/articles/the-article-name";
|
||||
|
||||
RKPathMatcher *pathMatcher1 = [RKPathMatcher pathMatcherWithPattern:@"/categories"];
|
||||
BOOL matches = [pathMatcher1 matchesPath:path tokenizeQueryStrings:NO parsedArguments:nil];
|
||||
expect(matches).to.equal(NO);
|
||||
|
||||
RKPathMatcher *pathMatcher2 = [RKPathMatcher pathMatcherWithPattern:@"/categories/:categoryName"];
|
||||
matches = [pathMatcher2 matchesPath:path tokenizeQueryStrings:NO parsedArguments:nil];
|
||||
expect(matches).to.equal(NO);
|
||||
|
||||
RKPathMatcher *pathMatcher3 = [RKPathMatcher pathMatcherWithPattern:@"/categories/:categorySlug/articles/:articleSlug"];
|
||||
matches = [pathMatcher3 matchesPath:path tokenizeQueryStrings:NO parsedArguments:nil];
|
||||
expect(matches).to.equal(YES);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user