diff --git a/Sources/Networking/Calls/NetworkingClient+Data.swift b/Sources/Networking/Calls/NetworkingClient+Data.swift index d197990..d9d3294 100644 --- a/Sources/Networking/Calls/NetworkingClient+Data.swift +++ b/Sources/Networking/Calls/NetworkingClient+Data.swift @@ -30,3 +30,26 @@ public extension NetworkingClient { request(.delete, route, params: params).publisher() } } + +public extension NetworkingClient { + + func get(_ route: String, params: Params = Params()) async throws -> Data { + try await request(.get, route, params: params).execute() + } + + func post(_ route: String, params: Params = Params()) async throws -> Data { + try await request(.post, route, params: params).execute() + } + + func put(_ route: String, params: Params = Params()) async throws -> Data { + try await request(.put, route, params: params).execute() + } + + func patch(_ route: String, params: Params = Params()) async throws -> Data { + try await request(.patch, route, params: params).execute() + } + + func delete(_ route: String, params: Params = Params()) async throws -> Data { + try await request(.delete, route, params: params).execute() + } +} diff --git a/Sources/Networking/Calls/NetworkingClient+Decodable.swift b/Sources/Networking/Calls/NetworkingClient+Decodable.swift index 4b9bb14..ed550e9 100644 --- a/Sources/Networking/Calls/NetworkingClient+Decodable.swift +++ b/Sources/Networking/Calls/NetworkingClient+Decodable.swift @@ -110,3 +110,83 @@ public extension NetworkingClient { .eraseToAnyPublisher() } } + + +public extension NetworkingClient { + + func get(_ route: String, + params: Params = Params(), + keypath: String? = nil) async throws -> T { + let json: Any = try await get(route, params: params) + let model:T = try NetworkingParser().toModel(json, keypath: keypath) + return model + } + + func get(_ route: String, + params: Params = Params(), + keypath: String? = nil) async throws -> T where T: Collection { + let keypath = keypath ?? defaultCollectionParsingKeyPath + let json: Any = try await get(route, params: params) + return try NetworkingParser().toModel(json, keypath: keypath) + } + + func post(_ route: String, + params: Params = Params(), + keypath: String? = nil) async throws -> T { + let json: Any = try await post(route, params: params) + return try NetworkingParser().toModel(json, keypath: keypath) + } + + func post(_ route: String, + params: Params = Params(), + keypath: String? = nil) async throws -> T where T: Collection { + let keypath = keypath ?? defaultCollectionParsingKeyPath + let json: Any = try await post(route, params: params) + return try NetworkingParser().toModel(json, keypath: keypath) + } + + func put(_ route: String, + params: Params = Params(), + keypath: String? = nil) async throws -> T { + let json: Any = try await put(route, params: params) + return try NetworkingParser().toModel(json, keypath: keypath) + } + + func put(_ route: String, + params: Params = Params(), + keypath: String? = nil) async throws -> T where T: Collection { + let keypath = keypath ?? defaultCollectionParsingKeyPath + let json: Any = try await put(route, params: params) + return try NetworkingParser().toModel(json, keypath: keypath) + } + + func patch(_ route: String, + params: Params = Params(), + keypath: String? = nil) async throws -> T { + let json: Any = try await patch(route, params: params) + return try NetworkingParser().toModel(json, keypath: keypath) + } + + func patch(_ route: String, + params: Params = Params(), + keypath: String? = nil) async throws -> T where T: Collection { + let keypath = keypath ?? defaultCollectionParsingKeyPath + let json: Any = try await patch(route, params: params) + return try NetworkingParser().toModel(json, keypath: keypath) + } + + func delete(_ route: String, + params: Params = Params(), + keypath: String? = nil) async throws -> T { + let json: Any = try await delete(route, params: params) + return try NetworkingParser().toModel(json, keypath: keypath) + } + + func delete(_ route: String, + params: Params = Params(), + keypath: String? = nil) async throws -> T where T: Collection { + let keypath = keypath ?? defaultCollectionParsingKeyPath + let json: Any = try await delete(route, params: params) + return try NetworkingParser().toModel(json, keypath: keypath) + } +} diff --git a/Sources/Networking/Calls/NetworkingClient+JSON.swift b/Sources/Networking/Calls/NetworkingClient+JSON.swift index 92810e8..5a3cfd6 100644 --- a/Sources/Networking/Calls/NetworkingClient+JSON.swift +++ b/Sources/Networking/Calls/NetworkingClient+JSON.swift @@ -31,6 +31,39 @@ public extension NetworkingClient { } } +public extension NetworkingClient { + + func get(_ route: String, params: Params = Params()) async throws -> Any { + let req = request(.get, route, params: params) + let data = try await req.execute() + return try JSONSerialization.jsonObject(with: data, options: []) + } + + func post(_ route: String, params: Params = Params()) async throws -> Any { + let req = request(.post, route, params: params) + let data = try await req.execute() + return try JSONSerialization.jsonObject(with: data, options: []) + } + + func put(_ route: String, params: Params = Params()) async throws -> Any { + let req = request(.put, route, params: params) + let data = try await req.execute() + return try JSONSerialization.jsonObject(with: data, options: []) + } + + func patch(_ route: String, params: Params = Params()) async throws -> Any { + let req = request(.patch, route, params: params) + let data = try await req.execute() + return try JSONSerialization.jsonObject(with: data, options: []) + } + + func delete(_ route: String, params: Params = Params()) async throws -> Any { + let req = request(.delete, route, params: params) + let data = try await req.execute() + return try JSONSerialization.jsonObject(with: data, options: []) + } +} + // Data to JSON extension Publisher where Output == Data { diff --git a/Sources/Networking/Calls/NetworkingClient+Void.swift b/Sources/Networking/Calls/NetworkingClient+Void.swift index 362cc28..c95497d 100644 --- a/Sources/Networking/Calls/NetworkingClient+Void.swift +++ b/Sources/Networking/Calls/NetworkingClient+Void.swift @@ -40,3 +40,31 @@ public extension NetworkingClient { .eraseToAnyPublisher() } } + +public extension NetworkingClient { + + func get(_ route: String, params: Params = Params()) async throws { + let req = request(.get, route, params: params) + _ = try await req.execute() + } + + func post(_ route: String, params: Params = Params()) async throws { + let req = request(.post, route, params: params) + _ = try await req.execute() + } + + func put(_ route: String, params: Params = Params()) async throws { + let req = request(.put, route, params: params) + _ = try await req.execute() + } + + func patch(_ route: String, params: Params = Params()) async throws { + let req = request(.patch, route, params: params) + _ = try await req.execute() + } + + func delete(_ route: String, params: Params = Params()) async throws { + let req = request(.delete, route, params: params) + _ = try await req.execute() + } +} diff --git a/Sources/Networking/NetworkingRequest.swift b/Sources/Networking/NetworkingRequest.swift index 3f37f92..80c4172 100644 --- a/Sources/Networking/NetworkingRequest.swift +++ b/Sources/Networking/NetworkingRequest.swift @@ -112,6 +112,36 @@ public class NetworkingRequest: NSObject { }.receive(on: DispatchQueue.main).eraseToAnyPublisher() } + func execute() async throws -> Data { + guard let urlRequest = buildURLRequest() else { + throw NetworkingError.unableToParseRequest + } + logger.log(request: urlRequest) + let config = sessionConfiguration ?? URLSessionConfiguration.default + let urlSession = URLSession(configuration: config, delegate: self, delegateQueue: nil) + return try await withCheckedThrowingContinuation { continuation in + urlSession.dataTask(with: urlRequest) { data, response, error in + guard let data = data, let response = response else { + if let error = error { + continuation.resume(throwing: error) + } + return + } + self.logger.log(response: response, data: data) + if let httpURLResponse = response as? HTTPURLResponse { + if !(200...299 ~= httpURLResponse.statusCode) { + var error = NetworkingError(errorCode: httpURLResponse.statusCode) + if let json = try? JSONSerialization.jsonObject(with: data, options: []) { + error.jsonPayload = json + } + continuation.resume(throwing: error) + } + } + continuation.resume(returning: data) + }.resume() + } + } + private func getURLWithParams() -> String { let urlString = baseURL + route if params.isEmpty { return urlString } diff --git a/Tests/NetworkingTests/DeleteRequestTests.swift b/Tests/NetworkingTests/DeleteRequestTests.swift index d3307e0..64ae5cf 100644 --- a/Tests/NetworkingTests/DeleteRequestTests.swift +++ b/Tests/NetworkingTests/DeleteRequestTests.swift @@ -49,6 +49,16 @@ class DeletehRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testDELETEVoidAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { "response": "OK" } + """ + let _: Void = try await network.delete("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "DELETE") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + } + func testDELETEDataWorks() { MockingURLProtocol.mockedResponse = """ @@ -73,6 +83,17 @@ class DeletehRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testDELETEDataAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { "response": "OK" } + """ + let data: Data = try await network.delete("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "DELETE") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + XCTAssertEqual(data, MockingURLProtocol.mockedResponse.data(using: String.Encoding.utf8)) + } + func testDELETEJSONWorks() { MockingURLProtocol.mockedResponse = """ @@ -103,6 +124,22 @@ class DeletehRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testDELETEJSONAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + {"response":"OK"} + """ + let json: Any = try await network.delete("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "DELETE") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + let data = try? JSONSerialization.data(withJSONObject: json, options: []) + let expectedResponseData = + """ + {"response":"OK"} + """.data(using: String.Encoding.utf8) + XCTAssertEqual(data, expectedResponseData) + } + func testDELETENetworkingJSONDecodableWorks() { MockingURLProtocol.mockedResponse = """ @@ -131,6 +168,7 @@ class DeletehRequestTests: XCTestCase { .store(in: &cancellables) waitForExpectations(timeout: 0.1) } + func testDELETEDecodableWorks() { MockingURLProtocol.mockedResponse = """ @@ -159,6 +197,21 @@ class DeletehRequestTests: XCTestCase { .store(in: &cancellables) waitForExpectations(timeout: 0.1) } + + func testDELETEDecodableAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { + "firstname":"John", + "lastname":"Doe", + } + """ + let userJSON: UserJSON = try await network.delete("/users/1") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "DELETE") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users/1") + XCTAssertEqual(userJSON.firstname, "John") + XCTAssertEqual(userJSON.lastname, "Doe") + } func testDELETEArrayOfDecodableWorks() { MockingURLProtocol.mockedResponse = @@ -196,6 +249,29 @@ class DeletehRequestTests: XCTestCase { .store(in: &cancellables) waitForExpectations(timeout: 0.1) } + + func testDELETEArrayOfDecodableAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + [ + { + "firstname":"John", + "lastname":"Doe" + }, + { + "firstname":"Jimmy", + "lastname":"Punchline" + } + ] + """ + let users: [UserJSON] = try await network.delete("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "DELETE") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + XCTAssertEqual(users[0].firstname, "John") + XCTAssertEqual(users[0].lastname, "Doe") + XCTAssertEqual(users[1].firstname, "Jimmy") + XCTAssertEqual(users[1].lastname, "Punchline") + } func testDELETEArrayOfDecodableWithKeypathWorks() { MockingURLProtocol.mockedResponse = diff --git a/Tests/NetworkingTests/GetRequestTests.swift b/Tests/NetworkingTests/GetRequestTests.swift index 21b1155..e54804a 100644 --- a/Tests/NetworkingTests/GetRequestTests.swift +++ b/Tests/NetworkingTests/GetRequestTests.swift @@ -47,6 +47,16 @@ final class GetRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testGETVoidAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { "response": "OK" } + """ + let _:Void = try await network.get("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "GET") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + } + func testGETDataWorks() { MockingURLProtocol.mockedResponse = """ @@ -72,6 +82,17 @@ final class GetRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testGETDataAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { "response": "OK" } + """ + let data: Data = try await network.get("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "GET") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + XCTAssertEqual(data, MockingURLProtocol.mockedResponse.data(using: String.Encoding.utf8)) + } + func testGETJSONWorks() { MockingURLProtocol.mockedResponse = """ @@ -89,7 +110,7 @@ final class GetRequestTests: XCTestCase { expectationFinished.fulfill() } } receiveValue: { (json: Any) in - let data = try? JSONSerialization.data(withJSONObject: json, options: []) + let data = try? JSONSerialization.data(withJSONObject: json, options: []) let expectedResponseData = """ {"response":"OK"} @@ -102,6 +123,23 @@ final class GetRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testGETJSONAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { "response": "OK" } + """ + let json: Any = try await network.get("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "GET") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + + let expectedResponseData = + """ + {"response":"OK"} + """.data(using: String.Encoding.utf8) + let data = try? JSONSerialization.data(withJSONObject: json, options: []) + XCTAssertEqual(data, expectedResponseData) + } + func testGETNetworkingJSONDecodableWorks() { MockingURLProtocol.mockedResponse = """ @@ -160,6 +198,21 @@ final class GetRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testGETNetworkingJSONDecodableAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { + "firstname":"John", + "lastname":"Doe", + } + """ + let userJSON: UserJSON = try await network.get("/posts/1") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "GET") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/posts/1") + XCTAssertEqual(userJSON.firstname, "John") + XCTAssertEqual(userJSON.lastname, "Doe") + } + func testGETArrayOfDecodableWorks() { MockingURLProtocol.mockedResponse = """ @@ -197,6 +250,30 @@ final class GetRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testGETArrayOfDecodableAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + [ + { + "firstname":"John", + "lastname":"Doe" + }, + { + "firstname":"Jimmy", + "lastname":"Punchline" + } + ] + """ + let users: [UserJSON] = try await network.get("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "GET") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + XCTAssertEqual(users[0].firstname, "John") + XCTAssertEqual(users[0].lastname, "Doe") + XCTAssertEqual(users[1].firstname, "Jimmy") + XCTAssertEqual(users[1].lastname, "Punchline") + } + + func testGETArrayOfDecodableWithKeypathWorks() { MockingURLProtocol.mockedResponse = """ diff --git a/Tests/NetworkingTests/PatchRequestTests.swift b/Tests/NetworkingTests/PatchRequestTests.swift index 1166248..7eb8e81 100644 --- a/Tests/NetworkingTests/PatchRequestTests.swift +++ b/Tests/NetworkingTests/PatchRequestTests.swift @@ -49,6 +49,16 @@ class PatchRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testPATCHVoidAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { "response": "OK" } + """ + let _:Void = try await network.patch("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "PATCH") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + } + func testPATCHDataWorks() { MockingURLProtocol.mockedResponse = """ @@ -73,6 +83,17 @@ class PatchRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testPATCHDataAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { "response": "OK" } + """ + let data: Data = try await network.patch("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "PATCH") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + XCTAssertEqual(data, MockingURLProtocol.mockedResponse.data(using: String.Encoding.utf8)) + } + func testPATCHJSONWorks() { MockingURLProtocol.mockedResponse = """ @@ -103,6 +124,22 @@ class PatchRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testPATCHJSONAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + {"response":"OK"} + """ + let json: Any = try await network.patch("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "PATCH") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + let data = try? JSONSerialization.data(withJSONObject: json, options: []) + let expectedResponseData = + """ + {"response":"OK"} + """.data(using: String.Encoding.utf8) + XCTAssertEqual(data, expectedResponseData) + } + func testPATCHNetworkingJSONDecodableWorks() { MockingURLProtocol.mockedResponse = """ @@ -160,6 +197,21 @@ class PatchRequestTests: XCTestCase { .store(in: &cancellables) waitForExpectations(timeout: 0.1) } + + func testPATCHDecodableAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { + "firstname":"John", + "lastname":"Doe", + } + """ + let user: UserJSON = try await network.patch("/users/1") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "PATCH") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users/1") + XCTAssertEqual(user.firstname, "John") + XCTAssertEqual(user.lastname, "Doe") + } func testPATCHArrayOfDecodableWorks() { MockingURLProtocol.mockedResponse = @@ -197,6 +249,29 @@ class PatchRequestTests: XCTestCase { .store(in: &cancellables) waitForExpectations(timeout: 0.1) } + + func testPATCHArrayOfDecodableAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + [ + { + "firstname":"John", + "lastname":"Doe" + }, + { + "firstname":"Jimmy", + "lastname":"Punchline" + } + ] + """ + let users: [UserJSON] = try await network.patch("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "PATCH") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + XCTAssertEqual(users[0].firstname, "John") + XCTAssertEqual(users[0].lastname, "Doe") + XCTAssertEqual(users[1].firstname, "Jimmy") + XCTAssertEqual(users[1].lastname, "Punchline") + } func testPATCHArrayOfDecodableWithKeypathWorks() { MockingURLProtocol.mockedResponse = diff --git a/Tests/NetworkingTests/PostRequestTests.swift b/Tests/NetworkingTests/PostRequestTests.swift index d9a9ec3..7b036db 100644 --- a/Tests/NetworkingTests/PostRequestTests.swift +++ b/Tests/NetworkingTests/PostRequestTests.swift @@ -49,6 +49,16 @@ class PostRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testPOSTVoidAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { "response": "OK" } + """ + let _: Void = try await network.post("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "POST") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + } + func testPOSTDataWorks() { MockingURLProtocol.mockedResponse = """ @@ -73,6 +83,17 @@ class PostRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testPOSTDataAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { "response": "OK" } + """ + let data: Data = try await network.post("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "POST") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + XCTAssertEqual(data, MockingURLProtocol.mockedResponse.data(using: String.Encoding.utf8)) + } + func testPOSTJSONWorks() { MockingURLProtocol.mockedResponse = """ @@ -103,6 +124,22 @@ class PostRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testPOSTJSONAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + {"response":"OK"} + """ + let json: Any = try await network.post("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "POST") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + let data = try? JSONSerialization.data(withJSONObject: json, options: []) + let expectedResponseData = + """ + {"response":"OK"} + """.data(using: String.Encoding.utf8) + XCTAssertEqual(data, expectedResponseData) + } + func testPOSTNetworkingJSONDecodableWorks() { MockingURLProtocol.mockedResponse = """ @@ -161,6 +198,21 @@ class PostRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testPOSTDecodableAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { + "firstname":"John", + "lastname":"Doe", + } + """ + let userJSON:UserJSON = try await network.post("/users/1") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "POST") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users/1") + XCTAssertEqual(userJSON.firstname, "John") + XCTAssertEqual(userJSON.lastname, "Doe") + } + func testPOSTArrayOfDecodableWorks() { MockingURLProtocol.mockedResponse = """ @@ -198,6 +250,29 @@ class PostRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testPOSTArrayOfDecodableAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + [ + { + "firstname":"John", + "lastname":"Doe" + }, + { + "firstname":"Jimmy", + "lastname":"Punchline" + } + ] + """ + let users: [UserJSON] = try await network.post("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "POST") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + XCTAssertEqual(users[0].firstname, "John") + XCTAssertEqual(users[0].lastname, "Doe") + XCTAssertEqual(users[1].firstname, "Jimmy") + XCTAssertEqual(users[1].lastname, "Punchline") + } + func testPOSTArrayOfDecodableWithKeypathWorks() { MockingURLProtocol.mockedResponse = """ diff --git a/Tests/NetworkingTests/PutRequestTests.swift b/Tests/NetworkingTests/PutRequestTests.swift index 707196c..18eb3b3 100644 --- a/Tests/NetworkingTests/PutRequestTests.swift +++ b/Tests/NetworkingTests/PutRequestTests.swift @@ -49,6 +49,16 @@ class PutRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testPUTVoidAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { "response": "OK" } + """ + let _: Void = try await network.put("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "PUT") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + } + func testPUTDataWorks() { MockingURLProtocol.mockedResponse = """ @@ -73,6 +83,17 @@ class PutRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testPUTDataAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { "response": "OK" } + """ + let data: Data = try await network.put("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "PUT") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + XCTAssertEqual(data, MockingURLProtocol.mockedResponse.data(using: String.Encoding.utf8)) + } + func testPUTJSONWorks() { MockingURLProtocol.mockedResponse = """ @@ -103,6 +124,22 @@ class PutRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testPUTJSONAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + {"response":"OK"} + """ + let json: Any = try await network.put("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "PUT") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + let data = try? JSONSerialization.data(withJSONObject: json, options: []) + let expectedResponseData = + """ + {"response":"OK"} + """.data(using: String.Encoding.utf8) + XCTAssertEqual(data, expectedResponseData) + } + func testPUTNetworkingJSONDecodableWorks() { MockingURLProtocol.mockedResponse = """ @@ -161,6 +198,21 @@ class PutRequestTests: XCTestCase { waitForExpectations(timeout: 0.1) } + func testPUTDecodableAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + { + "firstname":"John", + "lastname":"Doe", + } + """ + let user: UserJSON = try await network.put("/users/1") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "PUT") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users/1") + XCTAssertEqual(user.firstname, "John") + XCTAssertEqual(user.lastname, "Doe") + } + func testPUTArrayOfDecodableWorks() { MockingURLProtocol.mockedResponse = """ @@ -197,6 +249,29 @@ class PutRequestTests: XCTestCase { .store(in: &cancellables) waitForExpectations(timeout: 0.1) } + + func testPUTArrayOfDecodableAsyncWorks() async throws { + MockingURLProtocol.mockedResponse = + """ + [ + { + "firstname":"John", + "lastname":"Doe" + }, + { + "firstname":"Jimmy", + "lastname":"Punchline" + } + ] + """ + let users: [UserJSON] = try await network.put("/users") + XCTAssertEqual(MockingURLProtocol.currentRequest?.httpMethod, "PUT") + XCTAssertEqual(MockingURLProtocol.currentRequest?.url?.absoluteString, "https://mocked.com/users") + XCTAssertEqual(users[0].firstname, "John") + XCTAssertEqual(users[0].lastname, "Doe") + XCTAssertEqual(users[1].firstname, "Jimmy") + XCTAssertEqual(users[1].lastname, "Punchline") + } func testPUTArrayOfDecodableWithKeypathWorks() { MockingURLProtocol.mockedResponse =