Skip to content

Commit

Permalink
Add extra capabilities for on request handling (#139)
Browse files Browse the repository at this point in the history
* Add extra capabilities for on request handling

* Remove unneeded fastlane logic
  • Loading branch information
AvdLee authored Nov 7, 2022
1 parent 295b436 commit c009626
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Sources/Mocker/Mock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public struct Mock: Equatable {
@available(*, deprecated, message: "Use `onRequestHandler` instead.")
public var onRequest: OnRequest? {
set {
onRequestHandler = OnRequestHandler(callback: newValue)
onRequestHandler = OnRequestHandler(legacyCallback: newValue)
}
get {
onRequestHandler?.legacyCallback
Expand Down
56 changes: 52 additions & 4 deletions Sources/Mocker/OnRequestHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,66 @@ public struct OnRequestHandler {
legacyCallback = nil
}

init(callback: Mock.OnRequest?) {
/// Creates a new request handler using the given callback to call on request without parsing the body arguments.
/// - Parameter requestCallback: The callback which will be executed just before the request executes, containing the request.
public init(requestCallback: @escaping (_ request: URLRequest) -> Void) {
self.internalCallback = requestCallback
legacyCallback = nil
}

/// Creates a new request handler using the given callback to call on request without parsing the body arguments and without passing the request.
/// - Parameter callback: The callback which will be executed just before the request executes.
public init(callback: @escaping () -> Void) {
self.internalCallback = { _ in
callback()
}
legacyCallback = nil
}

/// Creates a new request handler using the given callback to call on request.
/// - Parameter jsonDictionaryCallback: The callback that executes just before the request executes, containing the HTTP Body Arguments as a JSON Object Dictionary.
public init(jsonDictionaryCallback: @escaping ((_ request: URLRequest, _ httpBodyArguments: [String: Any]?) -> Void)) {
self.internalCallback = { request in
guard
let httpBody = request.httpBodyStreamData() ?? request.httpBody,
let jsonObject = try? JSONSerialization.jsonObject(with: httpBody, options: .fragmentsAllowed) as? [String: Any]
else {
jsonDictionaryCallback(request, nil)
return
}
jsonDictionaryCallback(request, jsonObject)
}
self.legacyCallback = nil
}

/// Creates a new request handler using the given callback to call on request.
/// - Parameter jsonDictionaryCallback: The callback that executes just before the request executes, containing the HTTP Body Arguments as a JSON Object Array.
public init(jsonArrayCallback: @escaping ((_ request: URLRequest, _ httpBodyArguments: [[String: Any]]?) -> Void)) {
self.internalCallback = { request in
guard
let httpBody = request.httpBodyStreamData() ?? request.httpBody,
let jsonObject = try? JSONSerialization.jsonObject(with: httpBody, options: .fragmentsAllowed) as? [[String: Any]]
else {
jsonArrayCallback(request, nil)
return
}
jsonArrayCallback(request, jsonObject)
}
self.legacyCallback = nil
}

init(legacyCallback: Mock.OnRequest?) {
self.internalCallback = { request in
guard
let httpBody = request.httpBodyStreamData() ?? request.httpBody,
let jsonObject = try? JSONSerialization.jsonObject(with: httpBody, options: .fragmentsAllowed) as? [String: Any]
else {
callback?(request, nil)
legacyCallback?(request, nil)
return
}
callback?(request, jsonObject)
legacyCallback?(request, jsonObject)
}
self.legacyCallback = callback
self.legacyCallback = legacyCallback
}

func handleRequest(_ request: URLRequest) {
Expand Down
71 changes: 67 additions & 4 deletions Tests/MockerTests/MockerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ final class MockerTests: XCTestCase {
}

/// It should report post body arguments if they exist.
func testOnRequestPostBodyParameters() throws {
func testOnRequestLegacyPostBodyParameters() throws {
let onRequestExpectation = expectation(description: "Data request should start")

let expectedParameters = ["test": "value"]
Expand All @@ -331,7 +331,70 @@ final class MockerTests: XCTestCase {

wait(for: [onRequestExpectation], timeout: 2.0)
}


func testOnRequestDecodablePostBodyParameters() throws {
struct RequestParameters: Codable, Equatable {
let name: String
}

let onRequestExpectation = expectation(description: "Data request should start")

let expectedParameters = RequestParameters(name: UUID().uuidString)
var request = URLRequest(url: URL(string: "https://www.fakeurl.com")!)
request.httpMethod = Mock.HTTPMethod.post.rawValue
request.httpBody = try JSONEncoder().encode(expectedParameters)

var mock = Mock(url: request.url!, dataType: .json, statusCode: 200, data: [.post: Data()])
mock.onRequestHandler = .init(httpBodyType: RequestParameters.self, callback: { request, postBodyDecodable in
XCTAssertEqual(request.url, mock.request.url)
XCTAssertEqual(expectedParameters, postBodyDecodable)
onRequestExpectation.fulfill()
})
mock.register()

URLSession.shared.dataTask(with: request).resume()

wait(for: [onRequestExpectation], timeout: 2.0)
}

func testOnRequestJSONDictionaryPostBodyParameters() throws {
let onRequestExpectation = expectation(description: "Data request should start")

let expectedParameters = ["test": "value"]
var request = URLRequest(url: URL(string: "https://www.fakeurl.com")!)
request.httpMethod = Mock.HTTPMethod.post.rawValue
request.httpBody = try JSONSerialization.data(withJSONObject: expectedParameters, options: .prettyPrinted)

var mock = Mock(url: request.url!, dataType: .json, statusCode: 200, data: [.post: Data()])
mock.onRequestHandler = .init(jsonDictionaryCallback: { request, postBodyArguments in
XCTAssertEqual(request.url, mock.request.url)
XCTAssertEqual(expectedParameters, postBodyArguments as? [String: String])
onRequestExpectation.fulfill()
})
mock.register()

URLSession.shared.dataTask(with: request).resume()

wait(for: [onRequestExpectation], timeout: 2.0)
}

func testOnRequestCallbackWithoutRequestAndParameters() throws {
let onRequestExpectation = expectation(description: "Data request should start")

var request = URLRequest(url: URL(string: "https://www.fakeurl.com")!)
request.httpMethod = Mock.HTTPMethod.post.rawValue

var mock = Mock(url: request.url!, dataType: .json, statusCode: 200, data: [.post: Data()])
mock.onRequestHandler = .init(callback: {
onRequestExpectation.fulfill()
})
mock.register()

URLSession.shared.dataTask(with: request).resume()

wait(for: [onRequestExpectation], timeout: 2.0)
}

/// It should report post body arguments with top level collection type if they exist.
func testOnRequestPostBodyParametersWithTopLevelCollectionType() throws {
let onRequestExpectation = expectation(description: "Data request should start")
Expand All @@ -342,9 +405,9 @@ final class MockerTests: XCTestCase {
request.httpBody = try JSONSerialization.data(withJSONObject: expectedParameters, options: .prettyPrinted)

var mock = Mock(url: request.url!, dataType: .json, statusCode: 200, data: [.post: Data()])
mock.onRequestHandler = OnRequestHandler(httpBodyType: [[String:String]].self, callback: { request, postBodyArguments in
mock.onRequestHandler = OnRequestHandler(jsonArrayCallback: { request, postBodyArguments in
XCTAssertEqual(request.url, mock.request.url)
XCTAssertEqual(expectedParameters, postBodyArguments)
XCTAssertEqual(expectedParameters, postBodyArguments as? [[String: String]])
onRequestExpectation.fulfill()
})
mock.register()
Expand Down
5 changes: 0 additions & 5 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ import "./../Submodules/WeTransfer-iOS-CI/Fastlane/shared_lanes.rb"

desc "Run the tests and prepare for Danger"
lane :test do |options|

# Remove any leftover reports before running so CI won't fail due to an existing file.
# This also helps for local running this workflow frequently.
sh("rm -rf #{ENV['PWD']}/build/reports")

test_package(
package_name: 'Mocker',
package_path: ENV['PWD'],
Expand Down

0 comments on commit c009626

Please sign in to comment.