From 4874d3ad3737eae17865dd640b2f720d7210f7d1 Mon Sep 17 00:00:00 2001 From: Felix Lamouroux Date: Mon, 23 May 2016 16:10:11 +0200 Subject: [PATCH 1/2] Adds support for HTTPBody during testing when using NSURLSession --- CHANGELOG.md | 3 + OHHTTPStubs.podspec | 1 + .../OHHTTPStubs.xcodeproj/project.pbxproj | 38 ++++++++ .../NSMutableURLRequest+HTTPBodyTesting.h | 48 +++++++++++ .../NSMutableURLRequest+HTTPBodyTesting.m | 86 +++++++++++++++++++ .../OHHTTPStubs+NSURLSessionConfiguration.m | 34 +++----- .../NSURLSession/OHHTTPStubsMethodSwizzling.h | 51 +++++++++++ .../NSURLSession/OHHTTPStubsMethodSwizzling.m | 47 ++++++++++ .../Supporting Files/OHHTTPStubsUmbrella.h | 1 + 9 files changed, 288 insertions(+), 21 deletions(-) create mode 100644 OHHTTPStubs/Sources/NSURLSession/NSMutableURLRequest+HTTPBodyTesting.h create mode 100644 OHHTTPStubs/Sources/NSURLSession/NSMutableURLRequest+HTTPBodyTesting.m create mode 100644 OHHTTPStubs/Sources/NSURLSession/OHHTTPStubsMethodSwizzling.h create mode 100644 OHHTTPStubs/Sources/NSURLSession/OHHTTPStubsMethodSwizzling.m diff --git a/CHANGELOG.md b/CHANGELOG.md index de865def..8d3ea3f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ * Adjusted parsing of Mocktail files to allow headers to start on line 4. [@Ashton-W](https://github.com/Ashton-W), [#172](https://github.com/AliSoftware/OHHTTPStubs/pull/172) +* Allows access to the `HTTPBody` of POST request when using `NSURLSession` [(Wiki entry)](https://github.com/AliSoftware/OHHTTPStubs/wiki/Testing-for-the-request-body-in-your-stubs) + [@iosphere](https://github.com/iosphere/), [#166](https://github.com/AliSoftware/OHHTTPStubs/pull/166) + ## [5.0.0](https://github.com/AliSoftware/OHHTTPStubs/releases/tag/5.0.0) * Added `pathStartsWith(_:)` to the `Swift` helpers. diff --git a/OHHTTPStubs.podspec b/OHHTTPStubs.podspec index 5b9d0e40..c3da2277 100644 --- a/OHHTTPStubs.podspec +++ b/OHHTTPStubs.podspec @@ -53,6 +53,7 @@ Pod::Spec.new do |s| s.subspec 'NSURLSession' do |urlsession| urlsession.dependency 'OHHTTPStubs/Core' urlsession.source_files = "OHHTTPStubs/Sources/NSURLSession/*.{h,m}" + urlsession.private_header_files = "OHHTTPStubs/Sources/NSURLSession/OHHTTPStubsMethodSwizzling.h" end s.subspec 'JSON' do |json| diff --git a/OHHTTPStubs/OHHTTPStubs.xcodeproj/project.pbxproj b/OHHTTPStubs/OHHTTPStubs.xcodeproj/project.pbxproj index b397e5ca..3b40fa91 100644 --- a/OHHTTPStubs/OHHTTPStubs.xcodeproj/project.pbxproj +++ b/OHHTTPStubs/OHHTTPStubs.xcodeproj/project.pbxproj @@ -86,6 +86,13 @@ 09D0D29B1B67FF06004E7213 /* Compatibility.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 09D0D2981B67FED3004E7213 /* Compatibility.h */; }; 0D4BF5A17B4778591F08161F /* libPods-OHHTTPStubs tvOS Fmk Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BA8213D8FBCA73CF0607478B /* libPods-OHHTTPStubs tvOS Fmk Tests.a */; }; 0DB397E35DDB6808A5496D53 /* libPods-OHHTTPStubs Mac Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F49690D948DE88BBB4A36B11 /* libPods-OHHTTPStubs Mac Tests.a */; }; + 1B5632F01CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B5632EE1CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.h */; }; + 1B5632F11CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B5632EE1CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.h */; }; + 1B5632F21CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B5632EE1CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.h */; }; + 1B5632F31CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B5632EF1CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.m */; }; + 1B5632F41CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B5632EF1CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.m */; }; + 1B5632F51CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B5632EF1CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.m */; }; + 1B5632F61CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B5632EF1CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.m */; }; 1D0F8E7E1B6E31850049A7D2 /* MocktailTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D0F8E7D1B6E31850049A7D2 /* MocktailTests.m */; }; 1D0F8E801B6E31A70049A7D2 /* login.tail in Resources */ = {isa = PBXBuildFile; fileRef = 1D0F8E7F1B6E31A70049A7D2 /* login.tail */; }; 1D0F8E821B6E31B00049A7D2 /* MocktailFolder in Resources */ = {isa = PBXBuildFile; fileRef = 1D0F8E811B6E31B00049A7D2 /* MocktailFolder */; }; @@ -119,6 +126,14 @@ 725CD9BB1A9EB71A00F84C8B /* OHHTTPStubsResponse+JSON.h in Headers */ = {isa = PBXBuildFile; fileRef = 09110A721980606A00D175E4 /* OHHTTPStubsResponse+JSON.h */; settings = {ATTRIBUTES = (Public, ); }; }; 725CD9BC1A9EB71D00F84C8B /* OHHTTPStubsResponse+HTTPMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 09110A701980606A00D175E4 /* OHHTTPStubsResponse+HTTPMessage.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7B812F8D5510F916B78E671A /* libPods-OHHTTPStubs iOS Lib Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BFA846B11753DE97A1D563D0 /* libPods-OHHTTPStubs iOS Lib Tests.a */; }; + DC4658561CAD192600344232 /* NSMutableURLRequest+HTTPBodyTesting.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4658541CAD192600344232 /* NSMutableURLRequest+HTTPBodyTesting.m */; }; + DC4658571CAD19A200344232 /* NSMutableURLRequest+HTTPBodyTesting.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4658541CAD192600344232 /* NSMutableURLRequest+HTTPBodyTesting.m */; }; + DC4658581CAD19A200344232 /* NSMutableURLRequest+HTTPBodyTesting.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4658541CAD192600344232 /* NSMutableURLRequest+HTTPBodyTesting.m */; }; + DC46585A1CAD19A300344232 /* NSMutableURLRequest+HTTPBodyTesting.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4658541CAD192600344232 /* NSMutableURLRequest+HTTPBodyTesting.m */; }; + DC46585B1CAD245C00344232 /* NSMutableURLRequest+HTTPBodyTesting.h in Headers */ = {isa = PBXBuildFile; fileRef = DC4658551CAD192600344232 /* NSMutableURLRequest+HTTPBodyTesting.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DC46585C1CAD245D00344232 /* NSMutableURLRequest+HTTPBodyTesting.h in Headers */ = {isa = PBXBuildFile; fileRef = DC4658551CAD192600344232 /* NSMutableURLRequest+HTTPBodyTesting.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DC46585D1CAD245E00344232 /* NSMutableURLRequest+HTTPBodyTesting.h in Headers */ = {isa = PBXBuildFile; fileRef = DC4658551CAD192600344232 /* NSMutableURLRequest+HTTPBodyTesting.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DC46585E1CAD260F00344232 /* NSMutableURLRequest+HTTPBodyTesting.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DC4658551CAD192600344232 /* NSMutableURLRequest+HTTPBodyTesting.h */; }; EA100ABC1BE15BE400129352 /* OHHTTPStubs.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAA436A51BE1598D000E9E99 /* OHHTTPStubs.framework */; }; EA9D27231BE15C740078CAA0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA9D27221BE15C740078CAA0 /* Foundation.framework */; }; EA9D27241BE15CA00078CAA0 /* empty.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 221C34A61B0CCF9D00FCA8FF /* empty.bundle */; }; @@ -191,6 +206,7 @@ dstPath = "include/$(PRODUCT_NAME)"; dstSubfolderSpec = 16; files = ( + DC46585E1CAD260F00344232 /* NSMutableURLRequest+HTTPBodyTesting.h in CopyFiles */, 09D0D29B1B67FF06004E7213 /* Compatibility.h in CopyFiles */, 095981FC19806AF300807DBE /* OHHTTPStubs.h in CopyFiles */, 095981FD19806AF300807DBE /* OHHTTPStubsResponse.h in CopyFiles */, @@ -241,6 +257,8 @@ 095B1AD31AE30BA7009D1B56 /* OHPathHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OHPathHelpers.h; sourceTree = ""; }; 095B1AD41AE30BA7009D1B56 /* OHPathHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OHPathHelpers.m; sourceTree = ""; }; 09D0D2981B67FED3004E7213 /* Compatibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Compatibility.h; sourceTree = ""; }; + 1B5632EE1CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OHHTTPStubsMethodSwizzling.h; sourceTree = ""; }; + 1B5632EF1CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OHHTTPStubsMethodSwizzling.m; sourceTree = ""; }; 1D0F8E7D1B6E31850049A7D2 /* MocktailTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MocktailTests.m; path = "Test Suites/MocktailTests.m"; sourceTree = ""; }; 1D0F8E7F1B6E31A70049A7D2 /* login.tail */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = login.tail; path = ../login.tail; sourceTree = ""; }; 1D0F8E811B6E31B00049A7D2 /* MocktailFolder */ = {isa = PBXFileReference; lastKnownFileType = folder; name = MocktailFolder; path = ../MocktailFolder; sourceTree = ""; }; @@ -263,6 +281,8 @@ BFA846B11753DE97A1D563D0 /* libPods-OHHTTPStubs iOS Lib Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-OHHTTPStubs iOS Lib Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; C0E954CB8F11618F9510F283 /* Pods-OHHTTPStubs iOS Lib Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OHHTTPStubs iOS Lib Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-OHHTTPStubs iOS Lib Tests/Pods-OHHTTPStubs iOS Lib Tests.debug.xcconfig"; sourceTree = ""; }; DB9708EFC7D95D8EAE91EA78 /* Pods-OHHTTPStubs iOS Fmk Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OHHTTPStubs iOS Fmk Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-OHHTTPStubs iOS Fmk Tests/Pods-OHHTTPStubs iOS Fmk Tests.release.xcconfig"; sourceTree = ""; }; + DC4658541CAD192600344232 /* NSMutableURLRequest+HTTPBodyTesting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableURLRequest+HTTPBodyTesting.m"; sourceTree = ""; }; + DC4658551CAD192600344232 /* NSMutableURLRequest+HTTPBodyTesting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableURLRequest+HTTPBodyTesting.h"; sourceTree = ""; }; E2483255B84CAC7897D6E98C /* Pods-OHHTTPStubs Mac Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OHHTTPStubs Mac Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-OHHTTPStubs Mac Tests/Pods-OHHTTPStubs Mac Tests.release.xcconfig"; sourceTree = ""; }; EA100AB71BE15BE400129352 /* OHHTTPStubs tvOS Fmk Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "OHHTTPStubs tvOS Fmk Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; EA9D27221BE15C740078CAA0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS9.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; @@ -437,6 +457,10 @@ 09110A771980607200D175E4 /* NSURLSession Support */ = { isa = PBXGroup; children = ( + 1B5632EE1CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.h */, + 1B5632EF1CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.m */, + DC4658551CAD192600344232 /* NSMutableURLRequest+HTTPBodyTesting.h */, + DC4658541CAD192600344232 /* NSMutableURLRequest+HTTPBodyTesting.m */, 09110A781980608600D175E4 /* OHHTTPStubs+NSURLSessionConfiguration.m */, ); name = "NSURLSession Support"; @@ -577,6 +601,8 @@ 0959820119806B1E00807DBE /* OHHTTPStubsResponse+HTTPMessage.h in Headers */, 094906DF1B7F60EE00B047DA /* OHHTTPStubs+Mocktail.h in Headers */, 095B1AD71AE3138C009D1B56 /* OHPathHelpers.h in Headers */, + DC46585C1CAD245D00344232 /* NSMutableURLRequest+HTTPBodyTesting.h in Headers */, + 1B5632F11CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.h in Headers */, 09199FD01BD974F20014376D /* OHHTTPStubsUmbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -592,6 +618,8 @@ 725CD9BC1A9EB71D00F84C8B /* OHHTTPStubsResponse+HTTPMessage.h in Headers */, 094906DE1B7F60E200B047DA /* OHHTTPStubs+Mocktail.h in Headers */, 095B1AD61AE3138C009D1B56 /* OHPathHelpers.h in Headers */, + DC46585B1CAD245C00344232 /* NSMutableURLRequest+HTTPBodyTesting.h in Headers */, + 1B5632F01CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.h in Headers */, 09199FCF1BD974F10014376D /* OHHTTPStubsUmbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -607,6 +635,8 @@ EAA4369D1BE1598D000E9E99 /* OHHTTPStubsResponse+HTTPMessage.h in Headers */, EAA4369E1BE1598D000E9E99 /* OHHTTPStubs+Mocktail.h in Headers */, EAA4369F1BE1598D000E9E99 /* OHPathHelpers.h in Headers */, + DC46585D1CAD245E00344232 /* NSMutableURLRequest+HTTPBodyTesting.h in Headers */, + 1B5632F21CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.h in Headers */, EAA436A01BE1598D000E9E99 /* OHHTTPStubsUmbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1085,6 +1115,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DC4658561CAD192600344232 /* NSMutableURLRequest+HTTPBodyTesting.m in Sources */, + 1B5632F31CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.m in Sources */, 09110A6C1980605A00D175E4 /* OHHTTPStubs.m in Sources */, 09110A791980608600D175E4 /* OHHTTPStubs+NSURLSessionConfiguration.m in Sources */, 1D6DB8501B763B7A00FCF855 /* OHHTTPStubs+Mocktail.m in Sources */, @@ -1135,11 +1167,13 @@ 095981F619806AAC00807DBE /* OHHTTPStubs.m in Sources */, 095981FA19806AAC00807DBE /* OHHTTPStubs+NSURLSessionConfiguration.m in Sources */, 094906D81B7F520200B047DA /* OHHTTPStubs+Mocktail.m in Sources */, + 1B5632F51CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.m in Sources */, 095981F719806AAC00807DBE /* OHHTTPStubsResponse.m in Sources */, 095981F919806AAC00807DBE /* OHHTTPStubsResponse+JSON.m in Sources */, 095981F819806AAC00807DBE /* OHHTTPStubsResponse+HTTPMessage.m in Sources */, 0501A1A81C63E0C600B120AE /* OHHTTPStubsSwift.swift in Sources */, 095B1AD91AE31396009D1B56 /* OHPathHelpers.m in Sources */, + DC4658581CAD19A200344232 /* NSMutableURLRequest+HTTPBodyTesting.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1167,11 +1201,13 @@ 725CD9B41A9EB6F600F84C8B /* OHHTTPStubs.m in Sources */, 725CD9B81A9EB70000F84C8B /* OHHTTPStubs+NSURLSessionConfiguration.m in Sources */, 094906D71B7F520200B047DA /* OHHTTPStubs+Mocktail.m in Sources */, + 1B5632F41CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.m in Sources */, 725CD9B51A9EB6F800F84C8B /* OHHTTPStubsResponse.m in Sources */, 725CD9B71A9EB6FD00F84C8B /* OHHTTPStubsResponse+JSON.m in Sources */, 725CD9B61A9EB6FA00F84C8B /* OHHTTPStubsResponse+HTTPMessage.m in Sources */, 09199FD11BD98D1C0014376D /* OHHTTPStubsSwift.swift in Sources */, 095B1AD81AE31395009D1B56 /* OHPathHelpers.m in Sources */, + DC4658571CAD19A200344232 /* NSMutableURLRequest+HTTPBodyTesting.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1199,11 +1235,13 @@ EAA4368F1BE1598D000E9E99 /* OHHTTPStubs.m in Sources */, EAA436901BE1598D000E9E99 /* OHHTTPStubs+NSURLSessionConfiguration.m in Sources */, EAA436911BE1598D000E9E99 /* OHHTTPStubs+Mocktail.m in Sources */, + 1B5632F61CB2A9C200388C9B /* OHHTTPStubsMethodSwizzling.m in Sources */, EAA436921BE1598D000E9E99 /* OHHTTPStubsResponse.m in Sources */, EAA436931BE1598D000E9E99 /* OHHTTPStubsResponse+JSON.m in Sources */, EAA436941BE1598D000E9E99 /* OHHTTPStubsResponse+HTTPMessage.m in Sources */, EAA436951BE1598D000E9E99 /* OHHTTPStubsSwift.swift in Sources */, EAA436961BE1598D000E9E99 /* OHPathHelpers.m in Sources */, + DC46585A1CAD19A300344232 /* NSMutableURLRequest+HTTPBodyTesting.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/OHHTTPStubs/Sources/NSURLSession/NSMutableURLRequest+HTTPBodyTesting.h b/OHHTTPStubs/Sources/NSURLSession/NSMutableURLRequest+HTTPBodyTesting.h new file mode 100644 index 00000000..245829d9 --- /dev/null +++ b/OHHTTPStubs/Sources/NSURLSession/NSMutableURLRequest+HTTPBodyTesting.h @@ -0,0 +1,48 @@ +/*********************************************************************************** +* +* Copyright (c) 2016 Sebastian Hagedorn, Felix Lamouroux +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* 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 NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS 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. +* +***********************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +#pragma mark - Imports + +#import + +// This category is only useful when NSURLSession is present +#if defined(__IPHONE_7_0) || defined(__MAC_10_9) + +//////////////////////////////////////////////////////////////////////////////// +#pragma mark - NSURLRequest+CustomHTTPBody + +@interface NSURLRequest (CustomHTTPBody) +/** + * Unfortunately, when sending POST requests (with a body) using NSURLSession, + * by the time the request arrives at OHHTTPStubs, the HTTPBody of the + * NSURLRequest has been reset to nil. + * + * You can use this method to retrieve the HTTPBody for testing and use it to + * conditionally stub your requests. + */ +- (NSData *)OHHTTPStubs_HTTPBody; +@end + +#endif /* __IPHONE_7_0 || __MAC_10_9 */ diff --git a/OHHTTPStubs/Sources/NSURLSession/NSMutableURLRequest+HTTPBodyTesting.m b/OHHTTPStubs/Sources/NSURLSession/NSMutableURLRequest+HTTPBodyTesting.m new file mode 100644 index 00000000..457839d3 --- /dev/null +++ b/OHHTTPStubs/Sources/NSURLSession/NSMutableURLRequest+HTTPBodyTesting.m @@ -0,0 +1,86 @@ +/*********************************************************************************** +* +* Copyright (c) 2016 Sebastian Hagedorn, Felix Lamouroux +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* 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 NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS 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 "NSMutableURLRequest+HTTPBodyTesting.h" + +#if defined(__IPHONE_7_0) || defined(__MAC_10_9) + +//////////////////////////////////////////////////////////////////////////////// +#pragma mark - Imports + +#import "OHHTTPStubsMethodSwizzling.h" + +//////////////////////////////////////////////////////////////////////////////// +#pragma mark - NSURLRequest+CustomHTTPBody + +NSString * const OHHTTPStubs_HTTPBodyKey = @"HTTPBody"; + +@implementation NSURLRequest (CustomHTTPBody) + +- (NSData*)OHHTTPStubs_HTTPBody +{ + return [NSURLProtocol propertyForKey:OHHTTPStubs_HTTPBodyKey inRequest:self]; +} + +@end + +//////////////////////////////////////////////////////////////////////////////// +#pragma mark - NSMutableURLRequest+HTTPBodyTesting + +typedef void(*OHHHTTPStubsSetterIMP)(id, SEL, id); +static OHHHTTPStubsSetterIMP orig_setHTTPBody; + +static void OHHTTPStubs_setHTTPBody(id self, SEL _cmd, NSData* HTTPBody) +{ + // store the http body via NSURLProtocol + if (HTTPBody) { + [NSURLProtocol setProperty:HTTPBody forKey:OHHTTPStubs_HTTPBodyKey inRequest:self]; + } else { + // unfortunately resetting does not work properly as the NSURLSession also uses this to reset the property + } + + orig_setHTTPBody(self, _cmd, HTTPBody); +} + +/** + * Swizzles setHTTPBody: in order to maintain a copy of the http body for later + * reference and calls the original implementation. + * + * @warning Should not be used in production, testing only. + */ +@interface NSMutableURLRequest (HTTPBodyTesting) @end + +@implementation NSMutableURLRequest (HTTPBodyTesting) + ++ (void)load +{ + orig_setHTTPBody = (OHHHTTPStubsSetterIMP)OHHTTPStubsReplaceMethod(@selector(setHTTPBody:), + (IMP)OHHTTPStubs_setHTTPBody, + [NSMutableURLRequest class], + NO); +} + +@end + +#endif /* __IPHONE_7_0 || __MAC_10_9 */ diff --git a/OHHTTPStubs/Sources/NSURLSession/OHHTTPStubs+NSURLSessionConfiguration.m b/OHHTTPStubs/Sources/NSURLSession/OHHTTPStubs+NSURLSessionConfiguration.m index 8f7e6d3a..fe31acee 100644 --- a/OHHTTPStubs/Sources/NSURLSession/OHHTTPStubs+NSURLSessionConfiguration.m +++ b/OHHTTPStubs/Sources/NSURLSession/OHHTTPStubs+NSURLSessionConfiguration.m @@ -26,9 +26,8 @@ #if defined(__IPHONE_7_0) || defined(__MAC_10_9) #import - #import "OHHTTPStubs.h" - +#import "OHHTTPStubsMethodSwizzling.h" ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -43,20 +42,6 @@ static SessionConfigConstructor orig_defaultSessionConfiguration; static SessionConfigConstructor orig_ephemeralSessionConfiguration; -static SessionConfigConstructor OHHTTPStubsSwizzle(SEL selector, SessionConfigConstructor newImpl) -{ - Class cls = NSURLSessionConfiguration.class; - Class metaClass = object_getClass(cls); - - Method origMethod = class_getClassMethod(cls, selector); - SessionConfigConstructor origImpl = (SessionConfigConstructor)method_getImplementation(origMethod); - if (!class_addMethod(metaClass, selector, (IMP)newImpl, method_getTypeEncoding(origMethod))) - { - method_setImplementation(origMethod, (IMP)newImpl); - } - return origImpl; -} - static NSURLSessionConfiguration* OHHTTPStubs_defaultSessionConfiguration(id self, SEL _cmd) { NSURLSessionConfiguration* config = orig_defaultSessionConfiguration(self,_cmd); // call original method @@ -72,16 +57,23 @@ static SessionConfigConstructor OHHTTPStubsSwizzle(SEL selector, SessionConfigCo } @interface NSURLSessionConfiguration(OHHTTPStubsSupport) @end + @implementation NSURLSessionConfiguration(OHHTTPStubsSupport) + +(void)load { - orig_defaultSessionConfiguration = OHHTTPStubsSwizzle(@selector(defaultSessionConfiguration), - OHHTTPStubs_defaultSessionConfiguration); - orig_ephemeralSessionConfiguration = OHHTTPStubsSwizzle(@selector(ephemeralSessionConfiguration), - OHHTTPStubs_ephemeralSessionConfiguration); + orig_defaultSessionConfiguration = (SessionConfigConstructor)OHHTTPStubsReplaceMethod(@selector(defaultSessionConfiguration), + (IMP)OHHTTPStubs_defaultSessionConfiguration, + [NSURLSessionConfiguration class], + YES); + orig_ephemeralSessionConfiguration = (SessionConfigConstructor)OHHTTPStubsReplaceMethod(@selector(ephemeralSessionConfiguration), + (IMP)OHHTTPStubs_ephemeralSessionConfiguration, + [NSURLSessionConfiguration class], + YES); } + @end -#endif +#endif /* __IPHONE_7_0 || __MAC_10_9 */ diff --git a/OHHTTPStubs/Sources/NSURLSession/OHHTTPStubsMethodSwizzling.h b/OHHTTPStubs/Sources/NSURLSession/OHHTTPStubsMethodSwizzling.h new file mode 100644 index 00000000..443a6800 --- /dev/null +++ b/OHHTTPStubs/Sources/NSURLSession/OHHTTPStubsMethodSwizzling.h @@ -0,0 +1,51 @@ +/*********************************************************************************** + * + * Copyright (c) 2012 Olivier Halligon, 2016 Sebastian Hagedorn + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * 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 NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS 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. + * + ***********************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +#pragma mark - Imports + +#import + +//////////////////////////////////////////////////////////////////////////////// +#pragma mark - Method Swizzling Helpers + +/** + * Replaces the selector's associated method implementation with the + * given implementation (or adds it, if there was no existing one). + * + * @param selector The selector entry in the dispatch table. + * @param newImpl The implementation that will be associated with + * the given selector. + * @param affectedClass The class whose dispatch table will be altered. + * @param isClassMethod Set to YES if the selector denotes a class + * method, or NO if it is an instance method. + * @return The previous implementation associated with + * the swizzled selector. You should store the + * implementation and call it when overwriting + * the selector. + */ +__attribute__((warn_unused_result)) IMP OHHTTPStubsReplaceMethod(SEL selector, + IMP newImpl, + Class affectedClass, + BOOL isClassMethod); diff --git a/OHHTTPStubs/Sources/NSURLSession/OHHTTPStubsMethodSwizzling.m b/OHHTTPStubs/Sources/NSURLSession/OHHTTPStubsMethodSwizzling.m new file mode 100644 index 00000000..2aefcc7e --- /dev/null +++ b/OHHTTPStubs/Sources/NSURLSession/OHHTTPStubsMethodSwizzling.m @@ -0,0 +1,47 @@ +/*********************************************************************************** + * + * Copyright (c) 2012 Olivier Halligon, 2016 Sebastian Hagedorn + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * 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 NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS 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. + * + ***********************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +#pragma mark - Imports + +#import "OHHTTPStubsMethodSwizzling.h" + +////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - Method Swizzling Helpers + +IMP OHHTTPStubsReplaceMethod(SEL selector, + IMP newImpl, + Class affectedClass, + BOOL isClassMethod) +{ + Method origMethod = isClassMethod ? class_getClassMethod(affectedClass, selector) : class_getInstanceMethod(affectedClass, selector); + IMP origImpl = method_getImplementation(origMethod); + + if (!class_addMethod(isClassMethod ? object_getClass(affectedClass) : affectedClass, selector, newImpl, method_getTypeEncoding(origMethod))) + { + method_setImplementation(origMethod, newImpl); + } + + return origImpl; +} diff --git a/OHHTTPStubs/Supporting Files/OHHTTPStubsUmbrella.h b/OHHTTPStubs/Supporting Files/OHHTTPStubsUmbrella.h index 02125106..ef516e65 100644 --- a/OHHTTPStubs/Supporting Files/OHHTTPStubsUmbrella.h +++ b/OHHTTPStubs/Supporting Files/OHHTTPStubsUmbrella.h @@ -23,6 +23,7 @@ ***********************************************************************************/ #import "Compatibility.h" +#import "NSMutableURLRequest+HTTPBodyTesting.h" #import "OHHTTPStubs.h" #import "OHHTTPStubsResponse.h" From d77b1730c95253c3746c3c4da36e298a108400d5 Mon Sep 17 00:00:00 2001 From: Olivier Halligon Date: Tue, 24 May 2016 01:47:29 +0200 Subject: [PATCH 2/2] Removed useless import --- .../Sources/NSURLSession/OHHTTPStubs+NSURLSessionConfiguration.m | 1 - 1 file changed, 1 deletion(-) diff --git a/OHHTTPStubs/Sources/NSURLSession/OHHTTPStubs+NSURLSessionConfiguration.m b/OHHTTPStubs/Sources/NSURLSession/OHHTTPStubs+NSURLSessionConfiguration.m index fe31acee..6e885152 100644 --- a/OHHTTPStubs/Sources/NSURLSession/OHHTTPStubs+NSURLSessionConfiguration.m +++ b/OHHTTPStubs/Sources/NSURLSession/OHHTTPStubs+NSURLSessionConfiguration.m @@ -25,7 +25,6 @@ #import #if defined(__IPHONE_7_0) || defined(__MAC_10_9) -#import #import "OHHTTPStubs.h" #import "OHHTTPStubsMethodSwizzling.h"