Framework/ROADWebService/ROADWebserviceTest/RFWebServiceTest.m (376 lines of code) (raw):
//
// RFWebServiceTest.m
// ROADWebService
//
// Copyright (c) 2014 EPAM Systems, Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// Redistributions in binary form must reproduce the above copyright notice, this
// list of conditions and the following disclaimer in the documentation and/or
// other materials provided with the distribution.
// Neither the name of the EPAM Systems, Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// See the NOTICE file and the LICENSE file distributed with this work
// for additional information regarding copyright ownership and licensing
#import <XCTest/XCTest.h>
#import "RFWebServiceClient+DynamicTest.h"
#import "RFConcreteWebServiceClient.h"
#import "RFSerializableTestObject.h"
#import "RFDownloadFaker.h"
#import "RFDownloader.h"
#import "NSError+RFWebService.h"
#import "RFRequestTestProcessor.h"
#import "RFRequestTestAttribute.h"
@interface RFWebServiceTest : XCTestCase
{
NSCondition * condition;
BOOL authenticationFinished;
}
@end
@implementation RFWebServiceTest
+ (void)setUp {
[RFDownloadFaker setUp];
}
// Travis bug cause performing +setUp before each test
+ (void)tearDown {
[RFDownloadFaker tearDown];
}
- (void)testHeaderFieldsDictionaryAttachment {
__block BOOL isFinished = NO;
__block BOOL isSuccess = NO;
RFConcreteWebServiceClient *webClient = [[RFConcreteWebServiceClient alloc] initWithServiceRoot:@"http://test.headerfields.dictionary"];
[webClient testHeaderFieldsDictionaryAttachmentWithSuccess:^(id result) {
isFinished = YES;
isSuccess = ([result objectForKey:kRFWebServiceClientHeaderFieldsKey] != nil);
} failure:^(NSError *error) {
isFinished = YES;
}];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
}
XCTAssertTrue(isSuccess, @"Header fields for dictionary attachment is failed");
}
- (void)testHeaderFieldsObjectAttachment {
__block BOOL isFinished = NO;
__block BOOL isSuccess = NO;
RFConcreteWebServiceClient *webClient = [[RFConcreteWebServiceClient alloc] initWithServiceRoot:@"http://test.headerfields.object"];
[webClient testHeaderFieldsObjectAttachmentWithSuccess:^(id result) {
isFinished = YES;
isSuccess = ([result valueForKey:kRFWebServiceClientHeaderFieldsKey] != nil);
} failure:^(NSError *error) {
isFinished = YES;
}];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
}
XCTAssertTrue(isSuccess, @"Header fields object attachment is failed");
}
- (void)testHeaderFieldsArrayAttachment {
__block BOOL isFinished = NO;
__block BOOL isSuccess = NO;
RFConcreteWebServiceClient *webClient = [[RFConcreteWebServiceClient alloc] initWithServiceRoot:@"http://test.headerfields.array"];
[webClient testHeaderFieldsArrayAttachmentWithSuccess:^(id result) {
isFinished = YES;
isSuccess = ([result valueForKey:kRFWebServiceClientHeaderFieldsKey] != nil);
} failure:^(NSError *error) {
isFinished = YES;
}];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
}
XCTAssertTrue(isSuccess, @"Header fields array attachment is failed");
}
- (void)testHeaderFieldsNoBodyAttachment {
__block BOOL isFinished = NO;
__block BOOL isSuccess = NO;
RFConcreteWebServiceClient *webClient = [[RFConcreteWebServiceClient alloc] initWithServiceRoot:@"http://test.headerfields.nobody"];
[webClient testHeaderFieldsNoBodyAttachmentWithSuccess:^(id result) {
isFinished = YES;
isSuccess = ([result valueForKey:kRFWebServiceClientHeaderFieldsKey] != nil);
} failure:^(NSError *error) {
isFinished = YES;
}];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
}
XCTAssertTrue(isSuccess, @"Header fields no body attachment is failed");
}
- (void)testMultipartData {
__block BOOL isFinished = NO;
__block BOOL isSuccess = NO;
RFConcreteWebServiceClient *webClient = [[RFConcreteWebServiceClient alloc] initWithServiceRoot:@"http://test.multipart.data"];
RFFormData *attachment = [[RFFormData alloc] initWithName:@"image" data:[@"Random data 1" dataUsingEncoding:NSUTF8StringEncoding] fileName:@"imageName.jpg"];
[webClient testMultipartDataWithAttachment:attachment success:^(id result) {
isFinished = YES;
isSuccess = YES;
} failure:^(NSError *error) {
isFinished = YES;
}];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[[NSDate alloc] initWithTimeIntervalSinceNow:0.2]];
}
XCTAssertTrue(isSuccess, @"Multipart form data request is failed");
}
- (void)testMultipartDataArray {
__block BOOL isFinished = NO;
__block BOOL isSuccess = NO;
RFConcreteWebServiceClient *webClient = [[RFConcreteWebServiceClient alloc] initWithServiceRoot:@"http://test.multipart.data"];
NSArray *attachments = @[[[RFFormData alloc] initWithName:@"image" data:[@"Random data 1" dataUsingEncoding:NSUTF8StringEncoding] fileName:@"imageName.jpg"],
[[RFFormData alloc] initWithName:@"image" data:[@"Random data 2" dataUsingEncoding:NSUTF8StringEncoding]],
[[RFFormData alloc] initWithName:@"image" data:[@"Random data 3" dataUsingEncoding:NSUTF8StringEncoding] fileName:@"imageName2.jpg"]];
[webClient testMultipartDataWithAttachments:attachments success:^(id result) {
isFinished = YES;
isSuccess = YES;
} failure:^(NSError *error) {
isFinished = YES;
}];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[[NSDate alloc] initWithTimeIntervalSinceNow:0.2]];
}
XCTAssertTrue(isSuccess, @"Multipart form data request is failed");
}
- (void)testNilsInCompletionBlocks {
RFConcreteWebServiceClient *webClient = [[RFConcreteWebServiceClient alloc] initWithServiceRoot:@"http://test.method.without.blocks"];
RFFormData *attachment = [[RFFormData alloc] initWithName:@"image" data:[@"Random data 1" dataUsingEncoding:NSUTF8StringEncoding] fileName:@"imageName.jpg"];
[webClient testMultipartDataWithAttachment:attachment success:nil failure:nil];
__block BOOL isFinished = NO;
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[[NSDate alloc] initWithTimeIntervalSinceNow:0.2]];
isFinished = YES;
}
}
- (void)testCustomSerializer {
__block BOOL isFinished = NO;
__block BOOL isSuccess = NO;
__block id customSerializationResult;
RFSerializableTestObject *testObject = [RFSerializableTestObject testObject];
RFWebServiceClient *webClient = [[RFWebServiceClient alloc] initWithServiceRoot:@"http://test.serializer"];
[webClient testXMLSerializerWithObject:testObject withSuccess:^(id result) {
isSuccess = YES;
customSerializationResult = result;
isFinished = YES;
} failure:^(NSError *error) {
isFinished = YES;
}];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[[NSDate alloc] initWithTimeIntervalSinceNow:0.2]];
}
XCTAssertTrue(isSuccess, @"Custom serialization of web service request is failed!");
XCTAssertTrue([testObject isEqual:customSerializationResult], @"Custom deserialization of web service response is failed!");
}
- (void)testJsonSerializationEncoding {
__block BOOL isFinished = NO;
__block BOOL isSuccess = NO;
__block id jsonSerializationResult;
RFSerializableTestObject *testObject = [RFSerializableTestObject testObject];
testObject.name = @"Ваня Кузнецов";
testObject.city = @"Нью-Васюки";
RFWebServiceClient *webClient = [[RFWebServiceClient alloc] initWithServiceRoot:@"http://test.serializer"]; //@"http://127.0.0.1:8080/xml"];
[webClient testJsonSerializationEncoding:testObject withSuccess:^(id result) {
isSuccess = YES;
jsonSerializationResult = result;
isFinished = YES;
} failure:^(NSError *error) {
isFinished = YES;
}];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[[NSDate alloc] initWithTimeIntervalSinceNow:0.2]];
}
XCTAssertTrue(isSuccess, @"JSON serialization of web service request is failed!");
XCTAssertTrue([testObject isEqual:jsonSerializationResult], @"JSON deserialization of web service response is failed!");
}
- (void)testXMLSerializationEncoding {
__block BOOL isFinished = NO;
__block BOOL isSuccess = NO;
__block id xmlSerializationResult;
RFSerializableTestObject *testObject1 = [RFSerializableTestObject testObject];
testObject1.name = @"Ваня Кузнецов";
testObject1.city = @"City: Нью-Васюки";
RFWebServiceClient *webClient = [[RFWebServiceClient alloc] initWithServiceRoot:@"http://test.serializer"]; // @"http://127.0.0.1:8080/xml"
[webClient testXMLSerializationEncoding:testObject1 withSuccess:^(id result) {
isSuccess = YES;
xmlSerializationResult = result;
isFinished = YES;
} failure:^(NSError *error) {
isFinished = YES;
}];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[[NSDate alloc] initWithTimeIntervalSinceNow:0.2]];
}
XCTAssertTrue(isSuccess, @"XML serialization of web service request is failed!");
XCTAssertTrue([testObject1 isEqual:xmlSerializationResult], @"XML deserialization of web service response is failed!");
}
- (void)testGetWithJsonSerializationEncoding {
__block BOOL isFinished = NO;
__block BOOL isSuccess = NO;
__block id jsonSerializationResult1;
RFSerializableTestObject *testObject2 = [RFSerializableTestObject testObject];
testObject2.name = @"Ваня Кузнецов";
testObject2.city = @"Нью-Васюки";
RFWebServiceClient *webClient = [[RFWebServiceClient alloc] initWithServiceRoot:@"http://test.serializer/"]; //@"http://127.0.0.1:8080/xml"];
[webClient testGetWithJsonSerializationEncoding:testObject2 withSuccess:^(id result) {
isSuccess = YES;
jsonSerializationResult1 = result;
isFinished = YES;
} failure:^(NSError *error) {
isFinished = YES;
}];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[[NSDate alloc] initWithTimeIntervalSinceNow:0.2]];
}
XCTAssertTrue(isSuccess, @"JSON serialization of web service URL is failed!");
XCTAssertTrue([testObject2 isEqual:jsonSerializationResult1], @"JSON deserialization of web service response is failed!");
}
- (void)testDownloadingCancellation {
RFConcreteWebServiceClient *webClient = [[RFConcreteWebServiceClient alloc] initWithServiceRoot:@"http://test.simple.call"];
__block BOOL isFinished = NO;
__block int successFlag = 0;
const int kSuccessValue = 1;
id<RFWebServiceCancellable> downloadOperation = [webClient testSimpleWebServiceCallWithSuccess:^(id result) {
successFlag += 2;
isFinished = YES;
} failure:^(NSError *error) {
successFlag += 1;
isFinished = YES;
}];
[(NSObject *)downloadOperation performSelector:@selector(cancel) withObject:nil afterDelay:0.0];
[(NSObject *)downloadOperation performSelector:@selector(cancel) withObject:nil afterDelay:0.1];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[[NSDate alloc] initWithTimeIntervalSinceNow:2]];
}
XCTAssertEqual(successFlag, kSuccessValue, @"Web service cancellation finished with unexpected result!");
}
- (void)testCancelWithReason {
RFConcreteWebServiceClient *webClient = [[RFConcreteWebServiceClient alloc] initWithServiceRoot:@"http://test.simple.call"];
__block BOOL isFinished = NO;
__block NSError *cancelWithReasonError;
id<RFWebServiceCancellable> downloadOperation = [webClient testSimpleWebServiceCallWithSuccess:^(id result) {
isFinished = YES;
} failure:^(NSError *error) {
cancelWithReasonError = error;
isFinished = YES;
}];
NSObject *reason = [[NSObject alloc] init];
[downloadOperation cancelWithReason:reason];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[[NSDate alloc] initWithTimeIntervalSinceNow:2]];
}
XCTAssertEqual([cancelWithReasonError code], kRFWebServiceErrorCodeCancel, @"Web service cancellation finished with unexpected code!");
XCTAssertEqual([cancelWithReasonError userInfo][kRFWebServiceCancellationReason], reason, @"Web service cancellation finished with unexpected reason!");
}
- (void)testCancelWithoutReason {
RFConcreteWebServiceClient *webClient = [[RFConcreteWebServiceClient alloc] initWithServiceRoot:@"http://test.simple.call"];
__block BOOL isFinished = NO;
__block NSError *cancelError;
id<RFWebServiceCancellable> downloadOperation = [webClient testSimpleWebServiceCallWithSuccess:^(id result) {
isFinished = YES;
} failure:^(NSError *error) {
cancelError = error;
isFinished = YES;
}];
[downloadOperation cancel];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[[NSDate alloc] initWithTimeIntervalSinceNow:2]];
}
XCTAssertEqual([cancelError code], kRFWebServiceErrorCodeCancel, @"Web service cancellation finished with unexpected code!");
XCTAssertNil([cancelError userInfo][kRFWebServiceCancellationReason], @"Web service cancellation finished with unexpected reason!");
}
- (void)testRequestProcessorDelegate {
authenticationFinished = NO;
__block BOOL isFinished = NO;
RFRequestTestProcessor *testRequestProcessor = [[RFRequestTestProcessor alloc] init];
RFWebServiceClient *client = [[RFWebServiceClient alloc] initWithServiceRoot:@"https://test.simple.call/"];
client.requestProcessor = testRequestProcessor;
[client methodAttributeTestRequest:^(id result) {
isFinished = YES; /* reveived data ... */
} failure:^(NSError *error) {
isFinished = YES; /* reveived data ... */
}];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
}
XCTAssertEqual(testRequestProcessor.passedAttributes.count, 2, @"Attributes are not passed to the request processor.");
BOOL attributeFound = NO;
for (NSObject *currentAttribute in testRequestProcessor.passedAttributes) {
if ( [currentAttribute isKindOfClass:[RFRequestTestAttribute class]] ) {
attributeFound = YES;
}
}
XCTAssertTrue(attributeFound, @"Test attribute not passed to the request processor.");
}
- (void)testPutMethodToHaveBody {
RFConcreteWebServiceClient *client = [[RFConcreteWebServiceClient alloc] initWithServiceRoot:@"https://test.body.existence/"];
__block BOOL isFinished = NO;
__block BOOL isSuccess = NO;
[client testPutBodyPresenceWithData:@"Body"
success:^(id result) {
isSuccess = YES;
isFinished = YES; /* reveived data ... */
} failure:^(NSError *error) {
isFinished = YES; /* reveived data ... */
}];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
}
XCTAssertTrue(isSuccess, @"Put methods did not have body.");
}
- (void)testDownloadingPrepareAndProgressBlock {
RFConcreteWebServiceClient *webClient = [[RFConcreteWebServiceClient alloc] initWithServiceRoot:@"http://test.simple.call"];
__block BOOL isPrepareFinished = NO;
__block int prepareBlockCounter = 0;
__block BOOL isProgressFinished = NO;
__block int progressBlockCounter = 0;
__block BOOL isFinished = NO;
[webClient testDownloadingWithProgressBlock:^(float progress, long long expectedContentLenght) {
progressBlockCounter++;
isProgressFinished = YES;
} prepareBlock:^(NSMutableURLRequest *serviceRequest) {
prepareBlockCounter++;
isPrepareFinished = YES;
} success:^(id response) {
isFinished = YES;
} failure:^(NSError *error) {
isFinished = YES;
}];
while (!isPrepareFinished || !isProgressFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[[NSDate alloc] initWithTimeIntervalSinceNow:0.2]];
}
XCTAssertTrue(isProgressFinished, @"Web service progress block was not executed");
XCTAssertEqual(progressBlockCounter, 2, @"Web service progress block was unexpected number of times");
XCTAssertEqual(prepareBlockCounter, 1, @"Web service prepare block was unexpected number of times");
XCTAssertTrue(isPrepareFinished, @"Web service prepare block was not executed");
}
- (void)testPrepareBlockExecution {
RFConcreteWebServiceClient *webClient = [[RFConcreteWebServiceClient alloc] initWithServiceRoot:@"http://test.simple.call"];
__block BOOL isPrepareFinished = NO;
__block int prepareBlockCounter = 0;
__block BOOL isFinished = NO;
[webClient testDownloadingPrepareBlock:^(NSMutableURLRequest *serviceRequest) {
prepareBlockCounter++;
isPrepareFinished = YES;
} success:^(id response) {
isFinished = YES;
} failure:^(NSError *error) {
isFinished = YES;
}];
while (!isPrepareFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[[NSDate alloc] initWithTimeIntervalSinceNow:0.2]];
}
XCTAssertEqual(prepareBlockCounter, 1, @"Web service prepare block was unexpected number of times");
XCTAssertTrue(isPrepareFinished, @"Web service prepare block was not executed");
}
- (void)testDownloadingProgressBlock {
RFConcreteWebServiceClient *webClient = [[RFConcreteWebServiceClient alloc] initWithServiceRoot:@"http://test.simple.call"];
__block BOOL isProgressFinished = NO;
__block int progressBlockCounter = 0;
__block BOOL isStartProgressNotified = NO;
__block BOOL isEndProgressNotified = NO;
__block BOOL isFinished = NO;
[webClient testDownloadingProgressBlock:^(float progress, long long expectedContentLenght) {
progressBlockCounter++;
isProgressFinished = YES;
if (progress == 0) {
isStartProgressNotified = YES;
}
if (progress == 1.0) {
isEndProgressNotified = YES;
}
} success:^(id response) {
isFinished = YES;
} failure:^(NSError *error) {
isFinished = YES;
}];
while (!isFinished) {
[[NSRunLoop currentRunLoop] runUntilDate:[[NSDate alloc] initWithTimeIntervalSinceNow:0.2]];
}
XCTAssertTrue(isProgressFinished, @"Web service progress block was not executed");
XCTAssertTrue(isStartProgressNotified, @"Web service progress block notified about start downloading");
XCTAssertTrue(isEndProgressNotified, @"Web service progress block notified about finish downloading");
XCTAssertEqual(progressBlockCounter, 2, @"Web service progress block was unexpected number of times");
}
@end