From 972672d26fdf1727ca4943b7af98325992a346d8 Mon Sep 17 00:00:00 2001 From: Ellen Shapiro Date: Mon, 16 May 2016 20:16:53 -0500 Subject: [PATCH 1/7] Add support for adding the authorization header as part of the URL. --- VOKMockUrlProtocol.h | 8 ++++++++ VOKMockUrlProtocol.m | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/VOKMockUrlProtocol.h b/VOKMockUrlProtocol.h index 3bfba73..0572329 100644 --- a/VOKMockUrlProtocol.h +++ b/VOKMockUrlProtocol.h @@ -20,4 +20,12 @@ */ + (void)setTestBundle:(NSBundle *)bundle; +/** + * Allows you to encode authorizatation headers if desired. Defaults to NO. + * + * @param encodeAuthHeader YES to encode the `Authorization` header as part of + * the filename, NO to not do that. + */ ++ (void)setShouldEncodeAuthHeader:(BOOL)encodeAuthHeader; + @end diff --git a/VOKMockUrlProtocol.m b/VOKMockUrlProtocol.m index d90e33f..246fb78 100644 --- a/VOKMockUrlProtocol.m +++ b/VOKMockUrlProtocol.m @@ -11,6 +11,7 @@ #import #import +#import #import #import @@ -55,6 +56,12 @@ + (void)setTestBundle:(NSBundle *)bundle testBundle = bundle; } +static BOOL shouldEncodeAuthHeader = NO; ++ (void)setShouldEncodeAuthHeader:(BOOL)encodeAuthHeader +{ + shouldEncodeAuthHeader = encodeAuthHeader; +} + + (BOOL)canInitWithRequest:(NSURLRequest *)request { return YES; @@ -111,6 +118,16 @@ - (NSArray *)resourceNames [resourceName appendFormat:queryFormat, self.request.URL.query]; } + if (shouldEncodeAuthHeader) { + NSDictionary *headerDict = self.request.allHTTPHeaderFields; + NSString *authHeader = headerDict[kHTTPHeaderFieldAuthorization]; + if (authHeader) { + NSString *encodedHeader = [authHeader stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + NSString *authString = [NSString stringWithFormat:@"&authorization=%@", encodedHeader]; + [resourceName appendString:authString]; + } + } + // If the request is one that can have a body... if ([kHTTPMethodPost isEqualToString:self.request.HTTPMethod] || [kHTTPMethodPatch isEqualToString:self.request.HTTPMethod] From 40bb46449769d54f23ded13a4e67d1da4ebfe653 Mon Sep 17 00:00:00 2001 From: Ellen Shapiro Date: Mon, 16 May 2016 20:17:42 -0500 Subject: [PATCH 2/7] Add tests and mock data for using the auth header as part of the URL. --- Example/Tests/HttpFileParsingTests.m | 38 ++++++++++++++++++- ...th&authorization=Token%20I_am_a_token.http | 3 ++ 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 Example/VOKMockData/GET|-auth&authorization=Token%20I_am_a_token.http diff --git a/Example/Tests/HttpFileParsingTests.m b/Example/Tests/HttpFileParsingTests.m index 07034ba..7d51843 100644 --- a/Example/Tests/HttpFileParsingTests.m +++ b/Example/Tests/HttpFileParsingTests.m @@ -9,8 +9,11 @@ #import #import +#import #import +static NSString *const AuthToken = @"Token I_am_a_token"; + @interface HttpFileParsingTests : XCTestCase @end @@ -29,14 +32,24 @@ + (void)tearDown { // Un-register the mock URL protocol class. [NSURLProtocol unregisterClass:[VOKMockUrlProtocol class]]; - + [super tearDown]; +} + +- (void)tearDown +{ + // Make sure the URL protocol is not encoding auth params. + [VOKMockUrlProtocol setShouldEncodeAuthHeader:NO]; [super tearDown]; } - (void)verifyRequestWithURLString:(NSString *)urlString + authHeader:(NSString *)authHeader completion:(void (^)(NSData *data, NSHTTPURLResponse *response, NSError *error))completion { - NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]; + NSMutableURLRequest *request = [[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]] mutableCopy]; + + [request setValue:authHeader forHTTPHeaderField:kHTTPHeaderFieldAuthorization]; + XCTestExpectation *expectation = [self expectationWithDescription:NSStringFromSelector(_cmd)]; NSURLSession *session = [NSURLSession sharedSession]; [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *urlResponse, NSError *error) { @@ -49,6 +62,7 @@ - (void)verifyRequestWithURLString:(NSString *)urlString - (void)testNonexistentFileGives404 { [self verifyRequestWithURLString:@"http://example.com/DoesntExist.html" + authHeader:AuthToken completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { XCTAssertEqual(response.statusCode, kHTTPStatusCodeNotFound); XCTAssertEqual(data.length, 0); @@ -58,6 +72,7 @@ - (void)testNonexistentFileGives404 - (void)testHttpFileEmpty { [self verifyRequestWithURLString:@"http://example.com/empty" + authHeader:AuthToken completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { if (!data) { XCTFail(); @@ -73,6 +88,7 @@ - (void)testHttpFileEmpty - (void)testHttpFileBodyNoHeaders { [self verifyRequestWithURLString:@"http://example.com/bodyNoHeaders" + authHeader:AuthToken completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { if (!data) { XCTFail(); @@ -88,6 +104,7 @@ - (void)testHttpFileBodyNoHeaders - (void)testHttpFileHeadersNoBody { [self verifyRequestWithURLString:@"http://example.com/headersNoBody" + authHeader:AuthToken completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { if (!data) { XCTFail(); @@ -103,6 +120,7 @@ - (void)testHttpFileHeadersNoBody - (void)testHttpLongQueryFile { [self verifyRequestWithURLString:@"http://example.com/details?one=1&two=2&three=3&four=4&five=5&six=6&seven=7&eight=8&nine=9&ten=10&eleven=11&twelve=12&thirteen=13&fourteen=14&fifteen=15&sixteen=16&seventeen=17&eighteen=18&nineteen=19&twenty=20&twentyone=21&twntytwo=22&twentythree=23&twentyfour=24&twentyfive=25" + authHeader:AuthToken completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { if (!data) { XCTFail(); @@ -115,4 +133,20 @@ - (void)testHttpLongQueryFile }]; } +- (void)testHttpAuthorizationFile +{ + [VOKMockUrlProtocol setShouldEncodeAuthHeader:YES]; + [self verifyRequestWithURLString:@"http://example.com/auth" + authHeader:AuthToken + completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { + if (!data) { + XCTFail(); + return; + } + XCTAssertNil(error); + XCTAssertEqual(response.statusCode, kHTTPStatusCodeAccepted); + + }]; +} + @end \ No newline at end of file diff --git a/Example/VOKMockData/GET|-auth&authorization=Token%20I_am_a_token.http b/Example/VOKMockData/GET|-auth&authorization=Token%20I_am_a_token.http new file mode 100644 index 0000000..0e20fb6 --- /dev/null +++ b/Example/VOKMockData/GET|-auth&authorization=Token%20I_am_a_token.http @@ -0,0 +1,3 @@ +HTTP/1.1 202 Accepted + +{"favorite_dog_breed": "dogfish"} From 3bf4877425cefb8c2cb4e2e9f40dac45bdc2a386 Mon Sep 17 00:00:00 2001 From: Ellen Shapiro Date: Mon, 16 May 2016 20:20:47 -0500 Subject: [PATCH 3/7] Add documentation to README --- .../AppIcon.appiconset/Contents.json | 22 ++++++++++++++++++- README.md | 4 ++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Example/VOKMockUrlProtocol/Images.xcassets/AppIcon.appiconset/Contents.json b/Example/VOKMockUrlProtocol/Images.xcassets/AppIcon.appiconset/Contents.json index f697f61..eeea76c 100644 --- a/Example/VOKMockUrlProtocol/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/Example/VOKMockUrlProtocol/Images.xcassets/AppIcon.appiconset/Contents.json @@ -5,16 +5,31 @@ "size" : "29x29", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, { "idiom" : "ipad", "size" : "29x29", @@ -44,10 +59,15 @@ "idiom" : "ipad", "size" : "76x76", "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } -} +} \ No newline at end of file diff --git a/README.md b/README.md index e5a59eb..b8e18f7 100644 --- a/README.md +++ b/README.md @@ -86,3 +86,7 @@ In order to switch back and forth between mock and live, you can also take out t ### Using with Frameworks/Swift When `VOKMockUrlProtocol` is built as a framework (usually for use with Swift), make sure to call the `setTestBundle:` class method and pass in your test bundle. Since the default behavior is to fall back to the bundle for the current class, that would look in the Framework's bundle rather than the test bundle, and nothing would work. + +### Using with HTTP Authorization headers + +To verify that authorization headers are being sent properly, make sure to set `setShouldEncodeAuthHeader` to YES. This will verify that the value for the http header "Authorization" is set to an expected value. Otherwise, auth headers will not be verified. From 2c7884227e7d3f44cea51649430925acc88c5b01 Mon Sep 17 00:00:00 2001 From: Ellen Shapiro Date: Mon, 16 May 2016 20:21:16 -0500 Subject: [PATCH 4/7] Bump podspec --- VOKMockUrlProtocol.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VOKMockUrlProtocol.podspec b/VOKMockUrlProtocol.podspec index fec5bc3..a5fbd58 100644 --- a/VOKMockUrlProtocol.podspec +++ b/VOKMockUrlProtocol.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "VOKMockUrlProtocol" - s.version = "2.2.0" + s.version = "2.2.1" s.summary = "A url protocol that parses and returns fake responses with mock data." s.homepage = "https://github.com/vokal/VOKMockUrlProtocol" s.license = { :type => "MIT", :file => "LICENSE"} From 388c380c62964f0e3ceb8047b0cd9d5a38fccb79 Mon Sep 17 00:00:00 2001 From: Ellen Shapiro Date: Tue, 17 May 2016 14:49:09 -0500 Subject: [PATCH 5/7] Update to take a passed in array of headers to encode. --- Example/Tests/HttpFileParsingTests.m | 4 ++-- VOKMockUrlProtocol.h | 8 ++++---- VOKMockUrlProtocol.m | 30 +++++++++++++++++++--------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/Example/Tests/HttpFileParsingTests.m b/Example/Tests/HttpFileParsingTests.m index 7d51843..9b7b073 100644 --- a/Example/Tests/HttpFileParsingTests.m +++ b/Example/Tests/HttpFileParsingTests.m @@ -38,7 +38,7 @@ + (void)tearDown - (void)tearDown { // Make sure the URL protocol is not encoding auth params. - [VOKMockUrlProtocol setShouldEncodeAuthHeader:NO]; + [VOKMockUrlProtocol setHeadersToEncode:nil]; [super tearDown]; } @@ -135,7 +135,7 @@ - (void)testHttpLongQueryFile - (void)testHttpAuthorizationFile { - [VOKMockUrlProtocol setShouldEncodeAuthHeader:YES]; + [VOKMockUrlProtocol setHeadersToEncode:@[kHTTPHeaderFieldAuthorization]]; [self verifyRequestWithURLString:@"http://example.com/auth" authHeader:AuthToken completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { diff --git a/VOKMockUrlProtocol.h b/VOKMockUrlProtocol.h index 0572329..81c08e3 100644 --- a/VOKMockUrlProtocol.h +++ b/VOKMockUrlProtocol.h @@ -21,11 +21,11 @@ + (void)setTestBundle:(NSBundle *)bundle; /** - * Allows you to encode authorizatation headers if desired. Defaults to NO. + * Allows you to encode authorizatation headers if desired. Defaults to nil. * - * @param encodeAuthHeader YES to encode the `Authorization` header as part of - * the filename, NO to not do that. + * @param headers The names of headers to encode as part of the file name as strings, + * or nil to not encode any headers. */ -+ (void)setShouldEncodeAuthHeader:(BOOL)encodeAuthHeader; ++ (void)setHeadersToEncode:(NSArray*)headers; @end diff --git a/VOKMockUrlProtocol.m b/VOKMockUrlProtocol.m index 246fb78..adb2bbb 100644 --- a/VOKMockUrlProtocol.m +++ b/VOKMockUrlProtocol.m @@ -56,10 +56,10 @@ + (void)setTestBundle:(NSBundle *)bundle testBundle = bundle; } -static BOOL shouldEncodeAuthHeader = NO; -+ (void)setShouldEncodeAuthHeader:(BOOL)encodeAuthHeader +static NSArray *headersToEncode = nil; ++ (void)setHeadersToEncode:(NSArray*)headers { - shouldEncodeAuthHeader = encodeAuthHeader; + headersToEncode = headers; } + (BOOL)canInitWithRequest:(NSURLRequest *)request @@ -118,13 +118,25 @@ - (NSArray *)resourceNames [resourceName appendFormat:queryFormat, self.request.URL.query]; } - if (shouldEncodeAuthHeader) { + if (headersToEncode) { NSDictionary *headerDict = self.request.allHTTPHeaderFields; - NSString *authHeader = headerDict[kHTTPHeaderFieldAuthorization]; - if (authHeader) { - NSString *encodedHeader = [authHeader stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - NSString *authString = [NSString stringWithFormat:@"&authorization=%@", encodedHeader]; - [resourceName appendString:authString]; + NSMutableArray *allIncludedHeaders = [NSMutableArray array]; + for (NSString *headerName in headersToEncode) { + NSString *headerValue = headerDict[headerName]; + if (headerValue) { + NSString *headerString = [NSString stringWithFormat:@"%@=%@", headerName, headerValue]; + [allIncludedHeaders addObject:headerString]; + } + } + + NSString *fullHeaderString = [allIncludedHeaders componentsJoinedByString:@"&"]; + if (fullHeaderString.length > 0) { + NSString *encodedHeaderString = [fullHeaderString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + NSData *fullHeaderData = [encodedHeaderString dataUsingEncoding:NSUTF8StringEncoding]; + NSString *hashedHeaderString = [self sha256HexOfData:fullHeaderData]; + + [resourceNames addObject:[[resourceName stringByAppendingFormat:AppendSeparatorFormat, hashedHeaderString] mutableCopy]]; + [resourceName appendFormat:AppendSeparatorFormat, encodedHeaderString]; } } From f20b92d79b97b87c7b7939491dfe0d5006fd0a27 Mon Sep 17 00:00:00 2001 From: Ellen Shapiro Date: Tue, 17 May 2016 14:49:31 -0500 Subject: [PATCH 6/7] Update tests to verify muitlple headers are being included and ignored headers are ignored. --- Example/Tests/HttpFileParsingTests.m | 47 +++++++++++++++---- ...n%20I_am_a_token&Content-Language=en.http} | 0 ...th|Authorization=Token%20I_am_a_token.http | 3 ++ 3 files changed, 41 insertions(+), 9 deletions(-) rename Example/VOKMockData/{GET|-auth&authorization=Token%20I_am_a_token.http => GET|-auth|Authorization=Token%20I_am_a_token&Content-Language=en.http} (100%) create mode 100644 Example/VOKMockData/GET|-auth|Authorization=Token%20I_am_a_token.http diff --git a/Example/Tests/HttpFileParsingTests.m b/Example/Tests/HttpFileParsingTests.m index 9b7b073..78ed7d2 100644 --- a/Example/Tests/HttpFileParsingTests.m +++ b/Example/Tests/HttpFileParsingTests.m @@ -43,12 +43,17 @@ - (void)tearDown } - (void)verifyRequestWithURLString:(NSString *)urlString - authHeader:(NSString *)authHeader + additionalHeaders:(NSDictionary *)additionalHeaders completion:(void (^)(NSData *data, NSHTTPURLResponse *response, NSError *error))completion { NSMutableURLRequest *request = [[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]] mutableCopy]; - [request setValue:authHeader forHTTPHeaderField:kHTTPHeaderFieldAuthorization]; + if (additionalHeaders) { + for (NSString *key in additionalHeaders) { + NSString *value = additionalHeaders[key]; + [request setValue:value forHTTPHeaderField:key]; + } + } XCTestExpectation *expectation = [self expectationWithDescription:NSStringFromSelector(_cmd)]; NSURLSession *session = [NSURLSession sharedSession]; @@ -62,7 +67,7 @@ - (void)verifyRequestWithURLString:(NSString *)urlString - (void)testNonexistentFileGives404 { [self verifyRequestWithURLString:@"http://example.com/DoesntExist.html" - authHeader:AuthToken + additionalHeaders:nil completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { XCTAssertEqual(response.statusCode, kHTTPStatusCodeNotFound); XCTAssertEqual(data.length, 0); @@ -72,7 +77,7 @@ - (void)testNonexistentFileGives404 - (void)testHttpFileEmpty { [self verifyRequestWithURLString:@"http://example.com/empty" - authHeader:AuthToken + additionalHeaders:nil completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { if (!data) { XCTFail(); @@ -88,7 +93,7 @@ - (void)testHttpFileEmpty - (void)testHttpFileBodyNoHeaders { [self verifyRequestWithURLString:@"http://example.com/bodyNoHeaders" - authHeader:AuthToken + additionalHeaders:nil completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { if (!data) { XCTFail(); @@ -104,7 +109,7 @@ - (void)testHttpFileBodyNoHeaders - (void)testHttpFileHeadersNoBody { [self verifyRequestWithURLString:@"http://example.com/headersNoBody" - authHeader:AuthToken + additionalHeaders:nil completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { if (!data) { XCTFail(); @@ -120,7 +125,7 @@ - (void)testHttpFileHeadersNoBody - (void)testHttpLongQueryFile { [self verifyRequestWithURLString:@"http://example.com/details?one=1&two=2&three=3&four=4&five=5&six=6&seven=7&eight=8&nine=9&ten=10&eleven=11&twelve=12&thirteen=13&fourteen=14&fifteen=15&sixteen=16&seventeen=17&eighteen=18&nineteen=19&twenty=20&twentyone=21&twntytwo=22&twentythree=23&twentyfour=24&twentyfive=25" - authHeader:AuthToken + additionalHeaders:nil completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { if (!data) { XCTFail(); @@ -133,11 +138,35 @@ - (void)testHttpLongQueryFile }]; } -- (void)testHttpAuthorizationFile +- (void)testHttpHeadersEncoding +{ + [VOKMockUrlProtocol setHeadersToEncode:@[ + kHTTPHeaderFieldAuthorization, + kHTTPHeaderFieldContentLanguage, + ]]; + [self verifyRequestWithURLString:@"http://example.com/auth" + additionalHeaders: @{ + kHTTPHeaderFieldAuthorization: AuthToken, + kHTTPHeaderFieldContentLanguage: @"en", + } + completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { + if (!data) { + XCTFail(); + return; + } + XCTAssertNil(error); + XCTAssertEqual(response.statusCode, kHTTPStatusCodeAccepted); + }]; +} + +- (void)testHttpHeadersIgnoresUnencodedHeader { [VOKMockUrlProtocol setHeadersToEncode:@[kHTTPHeaderFieldAuthorization]]; [self verifyRequestWithURLString:@"http://example.com/auth" - authHeader:AuthToken + additionalHeaders: @{ + kHTTPHeaderFieldAuthorization: AuthToken, + kHTTPHeaderFieldContentLanguage: @"en", + } completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { if (!data) { XCTFail(); diff --git a/Example/VOKMockData/GET|-auth&authorization=Token%20I_am_a_token.http b/Example/VOKMockData/GET|-auth|Authorization=Token%20I_am_a_token&Content-Language=en.http similarity index 100% rename from Example/VOKMockData/GET|-auth&authorization=Token%20I_am_a_token.http rename to Example/VOKMockData/GET|-auth|Authorization=Token%20I_am_a_token&Content-Language=en.http diff --git a/Example/VOKMockData/GET|-auth|Authorization=Token%20I_am_a_token.http b/Example/VOKMockData/GET|-auth|Authorization=Token%20I_am_a_token.http new file mode 100644 index 0000000..0e20fb6 --- /dev/null +++ b/Example/VOKMockData/GET|-auth|Authorization=Token%20I_am_a_token.http @@ -0,0 +1,3 @@ +HTTP/1.1 202 Accepted + +{"favorite_dog_breed": "dogfish"} From 2b6f83b4d7cf33e79f89058b1a8d3a2cea7e997d Mon Sep 17 00:00:00 2001 From: Ellen Shapiro Date: Tue, 17 May 2016 15:19:03 -0500 Subject: [PATCH 7/7] Add test for headers + body data. --- Example/Tests/HttpFileParsingTests.m | 45 +++++++++++++++++++ ...oken&Content-Language=en|d3-foo3-bare.http | 3 ++ 2 files changed, 48 insertions(+) create mode 100644 Example/VOKMockData/POST|-auth|Authorization=Token%20I_am_a_token&Content-Language=en|d3-foo3-bare.http diff --git a/Example/Tests/HttpFileParsingTests.m b/Example/Tests/HttpFileParsingTests.m index 78ed7d2..549a2cc 100644 --- a/Example/Tests/HttpFileParsingTests.m +++ b/Example/Tests/HttpFileParsingTests.m @@ -44,10 +44,16 @@ - (void)tearDown - (void)verifyRequestWithURLString:(NSString *)urlString additionalHeaders:(NSDictionary *)additionalHeaders + bodyData:(NSData *)bodyData completion:(void (^)(NSData *data, NSHTTPURLResponse *response, NSError *error))completion { NSMutableURLRequest *request = [[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]] mutableCopy]; + if (bodyData) { + request.HTTPMethod = @"POST"; + request.HTTPBody = bodyData; + } + if (additionalHeaders) { for (NSString *key in additionalHeaders) { NSString *value = additionalHeaders[key]; @@ -68,6 +74,7 @@ - (void)testNonexistentFileGives404 { [self verifyRequestWithURLString:@"http://example.com/DoesntExist.html" additionalHeaders:nil + bodyData:nil completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { XCTAssertEqual(response.statusCode, kHTTPStatusCodeNotFound); XCTAssertEqual(data.length, 0); @@ -78,6 +85,7 @@ - (void)testHttpFileEmpty { [self verifyRequestWithURLString:@"http://example.com/empty" additionalHeaders:nil + bodyData:nil completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { if (!data) { XCTFail(); @@ -94,6 +102,7 @@ - (void)testHttpFileBodyNoHeaders { [self verifyRequestWithURLString:@"http://example.com/bodyNoHeaders" additionalHeaders:nil + bodyData:nil completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { if (!data) { XCTFail(); @@ -110,6 +119,7 @@ - (void)testHttpFileHeadersNoBody { [self verifyRequestWithURLString:@"http://example.com/headersNoBody" additionalHeaders:nil + bodyData:nil completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { if (!data) { XCTFail(); @@ -126,6 +136,7 @@ - (void)testHttpLongQueryFile { [self verifyRequestWithURLString:@"http://example.com/details?one=1&two=2&three=3&four=4&five=5&six=6&seven=7&eight=8&nine=9&ten=10&eleven=11&twelve=12&thirteen=13&fourteen=14&fifteen=15&sixteen=16&seventeen=17&eighteen=18&nineteen=19&twenty=20&twentyone=21&twntytwo=22&twentythree=23&twentyfour=24&twentyfive=25" additionalHeaders:nil + bodyData:nil completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { if (!data) { XCTFail(); @@ -149,6 +160,39 @@ - (void)testHttpHeadersEncoding kHTTPHeaderFieldAuthorization: AuthToken, kHTTPHeaderFieldContentLanguage: @"en", } + bodyData:nil + completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { + if (!data) { + XCTFail(); + return; + } + XCTAssertNil(error); + XCTAssertEqual(response.statusCode, kHTTPStatusCodeAccepted); + }]; +} + +- (void)testHttpHeadersWithJSONBody +{ + [VOKMockUrlProtocol setHeadersToEncode:@[ + kHTTPHeaderFieldAuthorization, + kHTTPHeaderFieldContentLanguage, + ]]; + + NSDictionary *foobar = @{ @"foo": @"bar" }; + NSError *error = nil; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:foobar + options:0 + error:&error]; + XCTAssertNil(error); + XCTAssertNotNil(jsonData); + + [self verifyRequestWithURLString:@"http://example.com/auth" + additionalHeaders: @{ + kHTTPHeaderFieldAuthorization: AuthToken, + kHTTPHeaderFieldContentLanguage: @"en", + kHTTPHeaderFieldContentType: @"application/json", + } + bodyData:jsonData completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { if (!data) { XCTFail(); @@ -167,6 +211,7 @@ - (void)testHttpHeadersIgnoresUnencodedHeader kHTTPHeaderFieldAuthorization: AuthToken, kHTTPHeaderFieldContentLanguage: @"en", } + bodyData:nil completion:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { if (!data) { XCTFail(); diff --git a/Example/VOKMockData/POST|-auth|Authorization=Token%20I_am_a_token&Content-Language=en|d3-foo3-bare.http b/Example/VOKMockData/POST|-auth|Authorization=Token%20I_am_a_token&Content-Language=en|d3-foo3-bare.http new file mode 100644 index 0000000..0e20fb6 --- /dev/null +++ b/Example/VOKMockData/POST|-auth|Authorization=Token%20I_am_a_token&Content-Language=en|d3-foo3-bare.http @@ -0,0 +1,3 @@ +HTTP/1.1 202 Accepted + +{"favorite_dog_breed": "dogfish"}