mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-04-29 13:15:34 +08:00
* Renamed RKObjectPaginator to RKPaginator for simplicity * Removed delegate on paginator in favor of simple success/failure blocks * Added `willMapDeserializedResponseBlock` for manipulating the response body before mapping begins * Added support for cancelling an in-progress pagination request
354 lines
15 KiB
Objective-C
354 lines
15 KiB
Objective-C
//
|
|
// RKPaginatorTest.m
|
|
// RestKit
|
|
//
|
|
// Created by Blake Watters on 12/29/11.
|
|
// Copyright (c) 2009-2012 RestKit. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
|
|
#import "RKTestEnvironment.h"
|
|
#import "RKPaginator.h"
|
|
#import "RKObjectMapperTestModel.h"
|
|
#import "RKURLEncodedSerialization.h"
|
|
|
|
@interface RKPaginator (Testability)
|
|
- (void)waitUntilFinished;
|
|
@end
|
|
|
|
@interface RKPaginatorTest : RKTestCase
|
|
@property (nonatomic, readonly) NSURL *paginationURL;
|
|
@property (nonatomic, readonly) RKObjectMapping *paginationMapping;
|
|
@property (nonatomic, readonly) RKResponseDescriptor *responseDescriptor;
|
|
@end
|
|
|
|
@implementation RKPaginatorTest
|
|
|
|
static NSString * const RKPaginatorTestResourcePathPattern = @"/paginate?per_page=:perPage&page=:currentPage";
|
|
|
|
- (void)setUp
|
|
{
|
|
[RKTestFactory setUp];
|
|
}
|
|
|
|
- (void)tearDown
|
|
{
|
|
[RKTestFactory tearDown];
|
|
}
|
|
|
|
- (RKResponseDescriptor *)responseDescriptor
|
|
{
|
|
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKObjectMapperTestModel class]];
|
|
[mapping addAttributeMappingsFromArray:@[@"name", @"age"]];
|
|
|
|
return [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:nil keyPath:@"entries" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
|
|
}
|
|
|
|
- (RKObjectMapping *)paginationMapping
|
|
{
|
|
RKObjectMapping *paginationMapping = [RKObjectMapping mappingForClass:[RKPaginator class]];
|
|
[paginationMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"current_page" toKeyPath:@"currentPage"]];
|
|
[paginationMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"per_page" toKeyPath:@"perPage"]];
|
|
[paginationMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"total_entries" toKeyPath:@"objectCount"]];
|
|
|
|
return paginationMapping;
|
|
}
|
|
|
|
- (NSURL *)paginationURL
|
|
{
|
|
return [NSURL URLWithString:RKPaginatorTestResourcePathPattern relativeToURL:[RKTestFactory baseURL]];
|
|
}
|
|
|
|
#pragma mark - Test Cases
|
|
|
|
- (void)testInitCopiesPatternURL
|
|
{
|
|
NSURL *patternURL = [NSURL URLWithString:@"http://restkit.org"];
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:patternURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
expect([paginator.patternURL absoluteString]).to.equal(@"http://restkit.org");
|
|
}
|
|
|
|
- (void)testInitDoesNotHavePageCount
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
expect([paginator hasPageCount]).to.equal(NO);
|
|
}
|
|
|
|
- (void)testInitDoesNotHaveObjectCount
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
expect([paginator hasObjectCount]).to.equal(NO);
|
|
}
|
|
|
|
- (void)testThatInitWithInvalidPaginationMappingRaisesError
|
|
{
|
|
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
NSException *exception = nil;
|
|
@try {
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:mapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
[paginator loadPage:1];
|
|
}
|
|
@catch (NSException *e) {
|
|
exception = e;
|
|
}
|
|
expect(exception).notTo.beNil();
|
|
expect([exception reason]).to.equal(@"The paginationMapping must have a target object class of `RKPaginator`");
|
|
}
|
|
|
|
- (void)testThatInitWithNilResponseDescriptorsRaisesError
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
NSException *exception = nil;
|
|
@try {
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:nil];
|
|
[paginator loadPage:1];
|
|
}
|
|
@catch (NSException *e) {
|
|
exception = e;
|
|
}
|
|
expect(exception).notTo.beNil();
|
|
expect([exception reason]).to.equal(@"Invalid parameter not satisfying: responseDescriptors");
|
|
}
|
|
|
|
- (void)testThatResourcePathPatternEvaluatesAgainstPaginator
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
id mockPaginator = [OCMockObject partialMockForObject:paginator];
|
|
NSUInteger currentPage = 1;
|
|
[[[mockPaginator stub] andReturnValue:OCMOCK_VALUE(currentPage)] currentPage];
|
|
expect([paginator.URL relativeString]).to.equal(@"/paginate?per_page=25&page=1");
|
|
}
|
|
|
|
- (void)testThatURLReturnedReflectsStateOfPaginator
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
id mockPaginator = [OCMockObject partialMockForObject:paginator];
|
|
NSUInteger currentPage = 1;
|
|
[[[mockPaginator stub] andReturnValue:OCMOCK_VALUE(currentPage)] currentPage];
|
|
expect([[mockPaginator URL] query]).to.equal(@"per_page=25&page=1");
|
|
}
|
|
|
|
- (void)testLoadingAPageOfObjects
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
[paginator loadPage:1];
|
|
[paginator waitUntilFinished];
|
|
expect(paginator.isLoaded).to.equal(YES);
|
|
}
|
|
|
|
- (void)testLoadingPageOfObjectMapsPerPage
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
[paginator loadPage:1];
|
|
[paginator waitUntilFinished];
|
|
expect(paginator.perPage).to.equal(3);
|
|
}
|
|
|
|
- (void)testLoadingPageOfObjectMapsTotalEntries
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
[paginator loadPage:1];
|
|
[paginator waitUntilFinished];
|
|
expect(paginator.objectCount).to.equal(6);
|
|
}
|
|
|
|
- (void)testLoadingPageOfObjectMapsCurrentPage
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
[paginator loadPage:1];
|
|
[paginator waitUntilFinished];
|
|
expect(paginator.currentPage).to.equal(1);
|
|
}
|
|
|
|
- (void)testLoadingPageOfObjectMapsEntriesToObjects
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
[paginator loadPage:1];
|
|
[paginator waitUntilFinished];
|
|
expect([paginator.mappingResult array]).to.haveCountOf(3);
|
|
NSArray *expectedNames = @[ @"Blake", @"Sarah", @"Colin" ];
|
|
expect([[paginator.mappingResult array] valueForKey:@"name"]).to.equal(expectedNames);
|
|
}
|
|
|
|
- (void)testLoadingPageOfObjectHasPageCount
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
[paginator loadPage:1];
|
|
[paginator waitUntilFinished];
|
|
expect([paginator hasPageCount]).to.beTruthy();
|
|
}
|
|
|
|
- (void)testLoadingPageOfObjectHasObjectCount
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
[paginator loadPage:1];
|
|
[paginator waitUntilFinished];
|
|
expect([paginator hasObjectCount]).to.beTruthy();
|
|
}
|
|
|
|
- (void)testInvocationOfCompletionBlockWithSuccess
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
__block NSArray *blockObjects = nil;
|
|
[paginator setCompletionBlockWithSuccess:^(RKPaginator *paginator, NSArray *objects, NSUInteger page) {
|
|
blockObjects = objects;
|
|
} failure:nil];
|
|
[paginator loadPage:1];
|
|
[paginator waitUntilFinished];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
expect(blockObjects).notTo.beNil();
|
|
});
|
|
}
|
|
|
|
- (void)testOnDidFailWithErrorBlockIsInvokedOnError
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
__block NSError *expectedError = nil;
|
|
[paginator setCompletionBlockWithSuccess:nil failure:^(RKPaginator *paginator, NSError *error) {
|
|
expectedError = error;
|
|
}];
|
|
[paginator loadPage:999];
|
|
[paginator waitUntilFinished];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
expect(expectedError).notTo.beNil();
|
|
});
|
|
}
|
|
|
|
- (void)testLoadingNextPageOfObjects
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
[paginator loadPage:1];
|
|
[paginator waitUntilFinished];
|
|
expect(paginator.currentPage).to.equal(1);
|
|
[paginator loadNextPage];
|
|
[paginator waitUntilFinished];
|
|
expect(paginator.currentPage).to.equal(2);
|
|
NSArray *names = @[ @"Asia", @"Roy", @"Lola" ];
|
|
expect([[paginator.mappingResult array] valueForKey:@"name"]).to.equal(names);
|
|
}
|
|
|
|
- (void)testLoadingPreviousPageOfObjects
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
[paginator loadPage:2];
|
|
[paginator waitUntilFinished];
|
|
expect(paginator.currentPage).to.equal(2);
|
|
[paginator loadPreviousPage];
|
|
[paginator waitUntilFinished];
|
|
expect(paginator.currentPage).to.equal(1);
|
|
NSArray *names = @[ @"Blake", @"Sarah", @"Colin" ];
|
|
expect([[paginator.mappingResult array] valueForKey:@"name"]).to.equal(names);
|
|
}
|
|
|
|
- (void)testFailureWhenLoadingAPageOfObjects
|
|
{
|
|
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
|
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
|
[paginator loadPage:3];
|
|
[paginator waitUntilFinished];
|
|
expect(paginator.error).notTo.beNil();
|
|
}
|
|
|
|
- (void)testKnowledgeOfHasANextPage
|
|
{
|
|
RKPaginator *paginator = [RKPaginator new];
|
|
id mockPaginator = [OCMockObject partialMockForObject:paginator];
|
|
BOOL isLoaded = YES;
|
|
NSUInteger perPage = 5;
|
|
NSUInteger pageCount = 3;
|
|
[[[mockPaginator stub] andReturnValue:OCMOCK_VALUE(isLoaded)] isLoaded];
|
|
[[[mockPaginator stub] andReturnValue:OCMOCK_VALUE(perPage)] perPage];
|
|
[[[mockPaginator stub] andReturnValue:OCMOCK_VALUE(pageCount)] pageCount];
|
|
|
|
NSUInteger currentPage = 1;
|
|
[[[mockPaginator expect] andReturnValue:OCMOCK_VALUE(currentPage)] currentPage];
|
|
assertThatBool([mockPaginator hasNextPage], is(equalToBool(YES)));
|
|
currentPage = 2;
|
|
[[[mockPaginator expect] andReturnValue:OCMOCK_VALUE(currentPage)] currentPage];
|
|
assertThatBool([mockPaginator hasNextPage], is(equalToBool(YES)));
|
|
currentPage = 3;
|
|
[[[mockPaginator expect] andReturnValue:OCMOCK_VALUE(currentPage)] currentPage];
|
|
assertThatBool([mockPaginator hasNextPage], is(equalToBool(NO)));
|
|
}
|
|
|
|
- (void)testHasNextPageRaisesExpectionWhenNotLoaded
|
|
{
|
|
RKPaginator *paginator = [RKPaginator new];
|
|
id mockPaginator = [OCMockObject partialMockForObject:paginator];
|
|
BOOL loaded = NO;
|
|
[[[mockPaginator stub] andReturnValue:OCMOCK_VALUE(loaded)] isLoaded];
|
|
STAssertThrows([mockPaginator hasNextPage], @"Expected exception due to isLoaded == NO");
|
|
}
|
|
|
|
- (void)testHasNextPageRaisesExpectionWhenPageCountIsUnknown
|
|
{
|
|
RKPaginator *paginator = [RKPaginator new];
|
|
id mockPaginator = [OCMockObject partialMockForObject:paginator];
|
|
BOOL loaded = YES;
|
|
[[[mockPaginator stub] andReturnValue:OCMOCK_VALUE(loaded)] isLoaded];
|
|
BOOL hasPageCount = NO;
|
|
[[[mockPaginator stub] andReturnValue:OCMOCK_VALUE(hasPageCount)] hasPageCount];
|
|
STAssertThrows([mockPaginator hasNextPage], @"Expected exception due to pageCount == NSUIntegerMax");
|
|
}
|
|
|
|
- (void)testHasPreviousPageRaisesExpectionWhenNotLoaded
|
|
{
|
|
RKPaginator *paginator = [RKPaginator new];
|
|
id mockPaginator = [OCMockObject partialMockForObject:paginator];
|
|
BOOL loaded = NO;
|
|
[[[mockPaginator stub] andReturnValue:OCMOCK_VALUE(loaded)] isLoaded];
|
|
STAssertThrows([mockPaginator hasPreviousPage], @"Expected exception due to isLoaded == NO");
|
|
}
|
|
|
|
- (void)testKnowledgeOfPreviousPage
|
|
{
|
|
RKPaginator *paginator = [RKPaginator new];
|
|
id mockPaginator = [OCMockObject partialMockForObject:paginator];
|
|
BOOL isLoaded = YES;
|
|
NSUInteger perPage = 5;
|
|
NSUInteger pageCount = 3;
|
|
[[[mockPaginator stub] andReturnValue:OCMOCK_VALUE(isLoaded)] isLoaded];
|
|
[[[mockPaginator stub] andReturnValue:OCMOCK_VALUE(perPage)] perPage];
|
|
[[[mockPaginator stub] andReturnValue:OCMOCK_VALUE(pageCount)] pageCount];
|
|
|
|
NSUInteger currentPage = 3;
|
|
[[[mockPaginator expect] andReturnValue:OCMOCK_VALUE(currentPage)] currentPage];
|
|
assertThatBool([mockPaginator hasPreviousPage], is(equalToBool(YES)));
|
|
currentPage = 2;
|
|
[[[mockPaginator expect] andReturnValue:OCMOCK_VALUE(currentPage)] currentPage];
|
|
assertThatBool([mockPaginator hasPreviousPage], is(equalToBool(YES)));
|
|
currentPage = 1;
|
|
[[[mockPaginator expect] andReturnValue:OCMOCK_VALUE(currentPage)] currentPage];
|
|
assertThatBool([mockPaginator hasPreviousPage], is(equalToBool(NO)));
|
|
}
|
|
|
|
@end
|