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