Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# OHHTTPStubs — CHANGELOG


## Master

* Added `hasFormBody(_:)` matcher.
[@417-72KI](https://github.com/417-72KI)

## [9.0.0](https://github.com/AliSoftware/OHHTTPStubs/releases/tag/9.0.0)

* Added support for Swift Package Manager and dropped OH from all class names.
Expand Down
50 changes: 50 additions & 0 deletions Sources/OHHTTPStubsSwift/OHHTTPStubsSwift.swift
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,56 @@ public func hasJsonBody(_ jsonObject: [AnyHashable : Any]) -> HTTPStubsTestBlock
}
#endif

#if swift(>=3.0)
/**
* Matcher testing that the `NSURLRequest` content-type is `application/x-www-form-urlencoded` and body contains a query parameter
*
* - Parameter params: The dictionary of query parameters to check the presence for
*
* - Returns: a matcher that returns true if the `NSURLRequest`'s body contains the same query items as the parameter value
*/
@available(iOS 8.0, OSX 10.10, *)
public func hasFormBody(_ params: [String: String?]) -> HTTPStubsTestBlock {
return hasFormBody(params.map(URLQueryItem.init))
}

/**
* Matcher testing that the `NSURLRequest` content-type is `application/x-www-form-urlencoded` and body contains a query parameter
*
* - Parameter queryItems: The array of query parameters to check the presence for
*
* - Returns: a matcher that returns true if the `NSURLRequest`'s body contains the same query items as the parameter value
*/
@available(iOS 8.0, OSX 10.10, *)
public func hasFormBody(_ queryItems: [URLQueryItem]) -> HTTPStubsTestBlock {
return { req in
guard
case "application/x-www-form-urlencoded"? = req.value(forHTTPHeaderField: "Content-Type"),
let httpBody = req.ohhttpStubs_httpBody,
let query = String(data: httpBody, encoding: .utf8)
else { return false }
let items: [URLQueryItem] = {
var comps = URLComponents()
comps.percentEncodedQuery = query
return comps.queryItems ?? []
}()
return items.sorted(by: { $0.name < $1.name }) == queryItems.sorted(by: { $0.name < $1.name })
}
}

/**
* Matcher testing that the `NSURLRequest` content-type is `application/x-www-form-urlencoded` and body contains a query parameter
*
* - Parameter queryItems: The variables of query parameters to check the presence for
*
* - Returns: a matcher that returns true if the `NSURLRequest`'s body contains the same query items as the parameter value
*/
@available(iOS 8.0, OSX 10.10, *)
public func hasFormBody(_ queryItems: URLQueryItem...) -> HTTPStubsTestBlock {
return hasFormBody(queryItems)
}
#endif

// MARK: Operators on HTTPStubsTestBlock

/**
Expand Down
47 changes: 47 additions & 0 deletions Tests/OHHTTPStubsSwiftTests/SwiftHelpersTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,53 @@ class SwiftHelpersTests : XCTestCase {
}
#endif

#if swift(>=3.0)
@available(iOS 8.0, OSX 10.10, *)
func testHasFormBodyIsTrue() {
func assertMatchesFormBody(_ formBody: String, _ expectedKeyValues: [String: String?], file: StaticString = #file, line: UInt = #line) {
var req = URLRequest(url: URL(string: "foo://bar")!)
req.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
req.httpBody = formBody.data(using: .utf8)
XCTAssertTrue(hasFormBody(expectedKeyValues)(req), file: file, line: line)
}

// Exact match
assertMatchesFormBody("foo=bar&baz=42&qux=true", ["foo": "bar", "baz": "42", "qux": "true"])
// Changed attribute order
assertMatchesFormBody("qux=true&foo=bar&baz=42", ["foo": "bar", "baz": "42", "qux": "true"])
// Contains key with no value
assertMatchesFormBody("foo=bar&baz&qux=42", ["foo": "bar", "baz": nil, "qux": "42"])
// Contains key with empty value
assertMatchesFormBody("foo=bar&baz=&qux=42", ["foo": "bar", "baz": "", "qux": "42"])
// Contains escaped character
assertMatchesFormBody("foo=bar%40baz", ["foo": "bar@baz"])
}
#endif

#if swift(>=3.0)
@available(iOS 8.0, OSX 10.10, *)
func testHasFormBodyIsFalse() {
func assertNotMatchesFormBody(_ formBody: String, _ expectedKeyValues: [String: String?], file: StaticString = #file, line: UInt = #line) {
var req = URLRequest(url: URL(string: "foo://bar")!)
req.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
req.httpBody = formBody.data(using: .utf8)
XCTAssertFalse(hasFormBody(expectedKeyValues)(req), file: file, line: line)
}
// Changed value
assertNotMatchesFormBody("foo=bar&baz=40", ["foo": "bar", "baz": "42"])
// Changed key
assertNotMatchesFormBody("foo=bar&qux=42", ["foo": "bar", "baz": "42"])
// Missing attribute
assertNotMatchesFormBody("foo=bar&baz=42&qux=true", ["foo": "bar", "baz": "42"])
// Extraneous attribute
assertNotMatchesFormBody("foo=bar&baz=42", ["foo": "bar", "baz": "42", "qux": "true"])
// Missing value
assertNotMatchesFormBody("foo=&bar=baz", ["foo": nil, "bar": "baz"])
// Extraneous value
assertNotMatchesFormBody("foo&bar=baz", ["foo": "", "baz": "42"])
}
#endif

let sampleURLs = [
// Absolute URLs
"scheme:",
Expand Down