-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
763 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import Foundation | ||
|
||
/// An open class that defines the base API. It will request data from a network pointing to a specific API endpoint. | ||
open class API<APIEndpoint: Endpoint> { | ||
private let network: Networking | ||
|
||
/// Initializes a new instance of the API class. | ||
public init() { | ||
network = Network() | ||
} | ||
|
||
/** | ||
Sends an asynchronous network request to a specific API endpoint. | ||
- Parameter endpoint: The API endpoint to which the request will be sent. | ||
- Throws: If there is an error during the network request. | ||
- Returns: The data response from the network request. | ||
*/ | ||
open func request(_ endpoint: APIEndpoint) async throws -> DataResponse { | ||
try await network.request( | ||
for: APIEndpoint.url.appending(path: endpoint.path), | ||
method: endpoint.method, | ||
headerFields: endpoint.headers, | ||
body: endpoint.body | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import Foundation | ||
|
||
/// Represents a response containing data and a URL response. | ||
public struct DataResponse { | ||
/// The data received in the response. | ||
public let data: Data? | ||
|
||
/// The URL response received from the server. | ||
public let response: URLResponse? | ||
|
||
/// Initializes a `DataResponse` with the given data and URL response. | ||
/// - Parameters: | ||
/// - data: The data received in the response. | ||
/// - response: The URL response received from the server. | ||
public init(data: Data?, response: URLResponse?) { | ||
self.data = data | ||
self.response = response | ||
} | ||
|
||
/// Initializes a `DataResponse` with a tuple containing data and URL response. | ||
/// - Parameters: | ||
/// - tuple: A tuple containing data as the first element and URL response as the second element. | ||
public init(_ tuple: (Data?, URLResponse?)) { | ||
self.init(data: tuple.0, response: tuple.1) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import Foundation | ||
|
||
/** | ||
This protocol defines the basic structure of an endpoint in a HTTP network request. | ||
- Note: | ||
This protocol requires any conforming type to provide the necessary properties for constructing a HTTP request. | ||
- Properties: | ||
- `url`: The base URL for the endpoint. | ||
- `method`: The HTTP request method (GET, POST, etc.) | ||
- `path`: The path component of the URL. | ||
- `headers`: The HTTP headers to include in the request. | ||
- `body`: The body of the HTTP request, if any. | ||
*/ | ||
public protocol Endpoint: Hashable { | ||
/// The base URL for the endpoint. | ||
static var url: URL { get } | ||
|
||
/// The HTTP request method (GET, POST, etc.) | ||
var method: HTTPRequestMethod { get } | ||
|
||
/// The path component of the URL. | ||
var path: String { get } | ||
|
||
/// The HTTP headers to include in the request. | ||
var headers: [String: String] { get } | ||
|
||
/// The body of the HTTP request, if any. | ||
var body: Data? { get } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/// Represents HTTP request methods. | ||
public enum HTTPRequestMethod: String { | ||
/// The HTTP GET method. | ||
case GET | ||
|
||
/// The HTTP HEAD method. | ||
case HEAD | ||
|
||
/// The HTTP POST method. | ||
case POST | ||
|
||
/// The HTTP PUT method. | ||
case PUT | ||
|
||
/// The HTTP DELETE method. | ||
case DELETE | ||
|
||
/// The HTTP CONNECT method. | ||
case CONNECT | ||
|
||
/// The HTTP OPTIONS method. | ||
case OPTIONS | ||
|
||
/// The HTTP TRACE method. | ||
case TRACE | ||
|
||
/// The HTTP PATCH method. | ||
case PATCH | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/** | ||
An open class that inherits from the base API class. It overrides the request method | ||
to use a mock network for testing purposes. | ||
- Parameter APIEndpoint: The endpoint where the API will point. | ||
- Returns: A mocked data response for testing. | ||
Usage: | ||
```swift | ||
let mockAPI = MockAPI<MyEndpoint>() | ||
let response = try await mockAPI.request(.someEndpoint) | ||
``` | ||
This will return a mock response using the data provided in the mockEndpoint body. | ||
*/ | ||
open class MockAPI<APIEndpoint: Endpoint>: API<APIEndpoint> { | ||
/** | ||
Sends an asynchronous network request to a specific API endpoint using a mock network. | ||
- Parameter endpoint: The API endpoint to which the request will be sent. | ||
- Throws: If there is an error during the network request. | ||
- Returns: A mocked data response for testing. The data will just be the body of the request and there will be no response. | ||
*/ | ||
open override func request(_ endpoint: APIEndpoint) async throws -> DataResponse { | ||
try await MockNetwork( | ||
responseData: endpoint.body, | ||
response: nil | ||
) | ||
.request( | ||
for: APIEndpoint.url.appending(path: endpoint.path), | ||
method: endpoint.method, | ||
headerFields: endpoint.headers, | ||
body: endpoint.body | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import Foundation | ||
|
||
/// A class that implements the `Networking` protocol to provide mock network responses. | ||
open class MockNetwork: Network { | ||
private let responseData: Data? | ||
private let response: URLResponse? | ||
|
||
public init( | ||
responseData: Data?, | ||
response: URLResponse? | ||
) { | ||
self.responseData = responseData | ||
self.response = response | ||
} | ||
|
||
/// Sends an Mock HTTP request. | ||
/// - Parameters: | ||
/// - url: The URL to which the request will be sent. | ||
/// - method: The HTTP method to be used. | ||
/// - headerFields: Header fields to include in the request. | ||
/// - body: Optional body to be including with the request. | ||
/// - Returns: A `DataResponse` object containing the response data and URL response. | ||
public override func request( | ||
for url: URL, | ||
method: HTTPRequestMethod, | ||
headerFields: [String: String], | ||
body: Data? | ||
) async throws -> DataResponse { | ||
DataResponse( | ||
data: responseData, | ||
response: response | ||
) | ||
} | ||
} |
Oops, something went wrong.