Skip to content

Commit

Permalink
Add URLResponse.isUnmockedInterceptedRequest
Browse files Browse the repository at this point in the history
Part of #46.
  • Loading branch information
lilyball committed Apr 24, 2019
1 parent 7b55118 commit ad8335e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 4 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,9 @@ work by you shall be dual licensed as above, without any additional terms or con
* Add computed property `HTTPManagerError.statusCode` that returns the failing status code for the error, or `nil` for `.unexpectedContentType` ([#60][]).
* Add Obj-C function `PMHTTPErrorGetStatusCode()` that returns the failing status code for the error, or `nil` for `PMHTTPErrorUnexpectedContentType` or for non-PMHTTP errors ([#60][]).
* Provide `PMHTTPStatusCodeErrorKey` user info key for more error types ([#59][]).
* Add computed property `URLResponse.isUnmockedInterceptedRequest` that can be used to test if a response comes from a request that was intercepted by the mock manager without a mock installed ([#46][]).

[#46]: https://github.com/postmates/PMHTTP/issues/46 "Consider making intercepted unmocked requests return 501 instead of 500 · Issue #46 · postmates/PMHTTP"
[#59]: https://github.com/postmates/PMHTTP/issues/59 "PMHTTPStatusCodeErrorKey should be used for unauthorized and unexpectedNoContent · Issue #59 · postmates/PMHTTP"
[#60]: https://github.com/postmates/PMHTTP/issues/60 "HTTPManagerError should have .statusCode property · Issue #60 · postmates/PMHTTP"
[#62]: https://github.com/postmates/PMHTTP/issues/62 "Unknown Hint Identifier for Image MIME Types · Issue #62 · postmates/PMHTTP"
Expand Down
34 changes: 30 additions & 4 deletions Sources/Mocking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ import PMJSON
/// **Thread safety:** All methods in this class are safe to call from any thread.
public final class HTTPMockManager: NSObject {
/// If `true`, any URL that is part of the current environment but not handled by any mocks
/// will return a 500 Internal Server Error. The default value is `false`.
/// will return an error. The default value is `false`.
///
/// - Note: Testing for unmocked intercepted requests should be done with
/// `URLResponse.isUnmockedInterceptedRequest`.
///
/// - SeeAlso: interceptUnhandledExternalURLs
@objc public var interceptUnhandledEnvironmentURLs: Bool {
get {
Expand All @@ -42,7 +46,11 @@ public final class HTTPMockManager: NSObject {
}
}
/// If `true`, any URL that is not part of the current environment but not handled by any mocks
/// will return a 500 Internal Server Error. The default value is `false`.
/// will return an error. The default value is `false`.
///
/// - Note: Testing for unmocked intercepted requests should be done with
/// `URLResponse.isUnmockedInterceptedRequest`.
///
/// - SeeAlso: interceptUnhandledEnvironmentURLs
@objc public var interceptUnhandledExternalURLs: Bool {
get {
Expand Down Expand Up @@ -596,6 +604,20 @@ public extension HTTPManagerParseRequest {
/// A token that can be used to unregister a mock from an `HTTPMockManager`.
@objc public protocol HTTPMockToken {}

@objc public extension URLResponse {
/// Returns whether the response represents an unmocked intercepted request.
///
/// When `HTTPMockManager` is configured to intercept unmocked requests, this property will
/// return `true` for the response generated for any such intercepted request. Otherwise it will
/// return `false` for any mocked request or any request that wasn't intercepted.
@objc(pmhttp_IsUnmockedInterceptedRequest)
var isUnmockedInterceptedRequest: Bool {
return (self as? HTTPURLResponse)?.allHeaderFields["X-PMHTTP-Mock"] as? String == "intercepted"
}
}

// MARK: - Internal and Private

internal class HTTPMock: HTTPMockToken, CustomStringConvertible {
enum MatchResult {
case noMatch
Expand Down Expand Up @@ -711,8 +733,12 @@ internal class HTTPMockInstance {
self.handler = handler
}

static let unhandledURLMock = HTTPMockInstance(queue: DispatchQueue.global(qos: .utility), parameters: [:]) { (request, parameters, completion) in
let response = HTTPURLResponse(url: request.url!, statusCode: 500, httpVersion: "HTTP/1.1", headerFields: ["Content-Type": "text/plain; charset=utf-8"])!
static let unhandledURLMock = HTTPMockInstance(queue: DispatchQueue.global(qos: .default), parameters: [:]) { (request, parameters, completion) in
let response = HTTPURLResponse(url: request.url!, statusCode: 500, httpVersion: "HTTP/1.1", headerFields: [
"Content-Type": "text/plain; charset=utf-8",
"Cache-Control": "no-store",
"X-PMHTTP-Mock": "intercepted"
])!
let data = "No mock found for URL.".data(using: String.Encoding.utf8)!
completion(response, data)
}
Expand Down
4 changes: 4 additions & 0 deletions Tests/MockingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class MockingTests: PMHTTPTestCase {
XCTAssertEqual((response as? HTTPURLResponse)?.statusCode, 200, "mock response status code")
XCTAssertEqual(response.mimeType, "text/plain", "mock response MIME type")
XCTAssertEqual(response.textEncodingName, "utf-8", "mock response text encoding")
XCTAssertFalse(response.isUnmockedInterceptedRequest, "mock response is unmocked intercepted request")
XCTAssertEqual(String(data: value, encoding: String.Encoding.utf8), "Mock response", "mock response body text")
}
waitForExpectations(timeout: 5, handler: nil)
Expand Down Expand Up @@ -561,6 +562,7 @@ class MockingTests: PMHTTPTestCase {
} else {
XCTFail("expected HTTPManagerError.failedResponse, found \(error)")
}
XCTAssertTrue(response?.isUnmockedInterceptedRequest ?? false, "mock response is unmocked intercepted request")
}
waitForExpectations(timeout: 5, handler: nil)

Expand All @@ -578,6 +580,7 @@ class MockingTests: PMHTTPTestCase {
} else {
XCTFail("expected HTTPManagerError.failedResponse, found \(error)")
}
XCTAssertTrue(response?.isUnmockedInterceptedRequest ?? false, "mock response is unmocked intercepted request")
}
waitForExpectations(timeout: 5, handler: nil)
}
Expand All @@ -590,6 +593,7 @@ class MockingTests: PMHTTPTestCase {
expectationForRequestSuccess(HTTP.request(GET: "http://\(httpServer.address)/foo")) { (task, response, value) in
XCTAssertEqual((response as? HTTPURLResponse)?.statusCode, 200, "status code")
XCTAssertEqual(String(data: value, encoding: String.Encoding.utf8), "Mock response", "body text")
XCTAssertFalse(response.isUnmockedInterceptedRequest, "mock response is unmocked intercepted request")
}
waitForExpectations(timeout: 5, handler: nil)

Expand Down

0 comments on commit ad8335e

Please sign in to comment.