From 82a774e92bf19b9a135004cca53b6e1e98dde052 Mon Sep 17 00:00:00 2001 From: Nick Lockwood Date: Fri, 17 Jul 2015 04:50:42 -0700 Subject: [PATCH] Added unit tests for gzip functionality --- .../UIExplorer.xcodeproj/project.pbxproj | 6 ++ .../UIExplorerUnitTests/RCTGzipTests.m | 81 +++++++++++++++++++ Libraries/Network/RCTNetworking.m | 15 ++-- React/Base/RCTUtils.m | 3 +- 4 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 Examples/UIExplorer/UIExplorerUnitTests/RCTGzipTests.m diff --git a/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj b/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj index db89c32b8..e6c9afc35 100644 --- a/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj +++ b/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 1300627F1B59179B0043FE5A /* RCTGzipTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1300627E1B59179B0043FE5A /* RCTGzipTests.m */; }; 13417FE91AA91432003F314A /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FE81AA91428003F314A /* libRCTImage.a */; }; 134180011AA9153C003F314A /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13417FEF1AA914B8003F314A /* libRCTText.a */; }; 1341802C1AA9178B003F314A /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1341802B1AA91779003F314A /* libRCTNetwork.a */; }; @@ -156,6 +157,7 @@ /* Begin PBXFileReference section */ 004D289E1AAF61C70097A701 /* UIExplorerUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UIExplorerUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 1300627E1B59179B0043FE5A /* RCTGzipTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTGzipTests.m; sourceTree = ""; }; 13417FE31AA91428003F314A /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = ""; }; 13417FEA1AA914B8003F314A /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = ""; }; 134180261AA91779003F314A /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = ""; }; @@ -357,6 +359,7 @@ 1497CFAA1B21F5E400C1F8F2 /* RCTSparseArrayTests.m */, 1497CFAB1B21F5E400C1F8F2 /* RCTUIManagerTests.m */, 138D6A151B53CD440074A87E /* RCTCacheTests.m */, + 1300627E1B59179B0043FE5A /* RCTGzipTests.m */, 143BC57E1B21E18100462512 /* Info.plist */, 14D6D7101B220EB3001FB087 /* libOCMock.a */, 14D6D7011B220AE3001FB087 /* OCMock */, @@ -783,6 +786,7 @@ 1497CFB01B21F5E400C1F8F2 /* RCTConvert_UIFontTests.m in Sources */, 144D21241B2204C5006DB32B /* RCTClippingTests.m in Sources */, 1497CFB21B21F5E400C1F8F2 /* RCTSparseArrayTests.m in Sources */, + 1300627F1B59179B0043FE5A /* RCTGzipTests.m in Sources */, 1497CFAF1B21F5E400C1F8F2 /* RCTConvert_NSURLTests.m in Sources */, 1497CFAE1B21F5E400C1F8F2 /* RCTContextExecutorTests.m in Sources */, 1497CFAD1B21F5E400C1F8F2 /* RCTBridgeTests.m in Sources */, @@ -1040,6 +1044,7 @@ "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/../../React/**", + "$(SRCROOT)/../../Libraries/**", ); IPHONEOS_DEPLOYMENT_TARGET = 7.0; MTL_ENABLE_DEBUG_INFO = YES; @@ -1094,6 +1099,7 @@ "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/../../React/**", + "$(SRCROOT)/../../Libraries/**", ); IPHONEOS_DEPLOYMENT_TARGET = 7.0; MTL_ENABLE_DEBUG_INFO = NO; diff --git a/Examples/UIExplorer/UIExplorerUnitTests/RCTGzipTests.m b/Examples/UIExplorer/UIExplorerUnitTests/RCTGzipTests.m new file mode 100644 index 000000000..5e74bf7c4 --- /dev/null +++ b/Examples/UIExplorer/UIExplorerUnitTests/RCTGzipTests.m @@ -0,0 +1,81 @@ +/** + * The examples provided by Facebook are for non-commercial testing and + * evaluation purposes only. + * + * Facebook reserves all rights not expressly granted. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL + * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#import +#import "RCTUtils.h" +#import "RCTNetworking.h" + +extern BOOL RCTIsGzippedData(NSData *data); + +@interface RCTNetworking (Private) + +- (void)buildRequest:(NSDictionary *)query + completionBlock:(void (^)(NSURLRequest *request))block; + +@end + +@interface RCTGzipTests : XCTestCase + +@end + +@implementation RCTGzipTests + +- (void)testGzip +{ + //set up data + NSString *inputString = @"Hello World!"; + NSData *inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding]; + + //compress + NSData *outputData = RCTGzipData(inputData, -1); + XCTAssertTrue(RCTIsGzippedData(outputData)); +} + +- (void)testDontRezipZippedData +{ + //set up data + NSString *inputString = @"Hello World!"; + NSData *inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding]; + + //compress + NSData *compressedData = RCTGzipData(inputData, -1); + inputString = [[NSString alloc] initWithData:compressedData encoding:NSUTF8StringEncoding]; + + //compress again + NSData *outputData = RCTGzipData(inputData, -1); + NSString *outputString = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding]; + XCTAssertEqualObjects(outputString, inputString); +} + +- (void)testRequestBodyEncoding +{ + NSDictionary *query = @{ + @"url": @"http://example.com", + @"method": @"POST", + @"data": @{@"string": @"Hello World"}, + @"headers": @{@"Content-Encoding": @"gzip"}, + }; + + RCTNetworking *networker = [[RCTNetworking alloc] init]; + __block NSURLRequest *request = nil; + [networker buildRequest:query completionBlock:^(NSURLRequest *_request) { + request = _request; + }]; + + XCTAssertNotNil(request); + XCTAssertNotNil(request.HTTPBody); + XCTAssertTrue(RCTIsGzippedData(request.HTTPBody)); +} + +@end diff --git a/Libraries/Network/RCTNetworking.m b/Libraries/Network/RCTNetworking.m index d86b00950..df102e594 100644 --- a/Libraries/Network/RCTNetworking.m +++ b/Libraries/Network/RCTNetworking.m @@ -230,15 +230,13 @@ RCT_EXPORT_MODULE() } - (void)buildRequest:(NSDictionary *)query - responseSender:(RCTResponseSenderBlock)responseSender + completionBlock:(void (^)(NSURLRequest *request))block { NSURL *URL = [RCTConvert NSURL:query[@"url"]]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; request.HTTPMethod = [[RCTConvert NSString:query[@"method"]] uppercaseString] ?: @"GET"; request.allHTTPHeaderFields = [RCTConvert NSDictionary:query[@"headers"]]; - BOOL incrementalUpdates = [RCTConvert BOOL:query[@"incrementalUpdates"]]; - NSDictionary *data = [RCTConvert NSDictionary:query[@"data"]]; [self processDataForHTTPQuery:data callback:^(NSError *error, NSDictionary *result) { if (error) { @@ -258,9 +256,7 @@ RCT_EXPORT_MODULE() [request setValue:[@(request.HTTPBody.length) description] forHTTPHeaderField:@"Content-Length"]; } - [self sendRequest:request - incrementalUpdates:incrementalUpdates - responseSender:responseSender]; + block(request); }]; } @@ -464,7 +460,12 @@ RCT_EXPORT_MODULE() RCT_EXPORT_METHOD(sendRequest:(NSDictionary *)query responseSender:(RCTResponseSenderBlock)responseSender) { - [self buildRequest:query responseSender:responseSender]; + [self buildRequest:query completionBlock:^(NSURLRequest *request) { + + BOOL incrementalUpdates = [RCTConvert BOOL:query[@"incrementalUpdates"]]; + [self sendRequest:request incrementalUpdates:incrementalUpdates + responseSender:responseSender]; + }]; } RCT_EXPORT_METHOD(cancelRequest:(NSNumber *)requestID) diff --git a/React/Base/RCTUtils.m b/React/Base/RCTUtils.m index d342c3be4..724a9c368 100644 --- a/React/Base/RCTUtils.m +++ b/React/Base/RCTUtils.m @@ -308,7 +308,8 @@ NSURL *RCTDataURL(NSString *mimeType, NSData *data) [data base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0]]]; } -static BOOL RCTIsGzippedData(NSData *data) +BOOL RCTIsGzippedData(NSData *); // exposed for unit testing purposes +BOOL RCTIsGzippedData(NSData *data) { UInt8 *bytes = (UInt8 *)data.bytes; return (data.length >= 2 && bytes[0] == 0x1f && bytes[1] == 0x8b);