From bb2b05b57f26d1b721c080f859cd79148ffaf077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Neto?= Date: Mon, 29 May 2023 08:58:00 +0100 Subject: [PATCH] bkp --- .../xcschemes/ToolboxAPIClientTests.xcscheme | 52 ------------------- .../ToolboxAPIClient/BaseNetworkWorker.swift | 36 +++++++++++-- Sources/ToolboxAPIClient/Errors.swift | 19 +++++++ .../Network/Story/Errors/Errors.swift | 23 ++++++++ .../Story/Manager/LoginManagerAPI.swift | 10 ++-- .../Network/Story/Targets/LoginTarget.swift | 6 +++ .../Tests/app_zeneto_api_moduleTests.swift | 48 +++++++++++++++-- 7 files changed, 131 insertions(+), 63 deletions(-) delete mode 100644 .swiftpm/xcode/xcshareddata/xcschemes/ToolboxAPIClientTests.xcscheme create mode 100644 Sources/ToolboxAPIClient/Errors.swift create mode 100644 Tests/ToolboxAPIClientTests/Network/Story/Errors/Errors.swift diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/ToolboxAPIClientTests.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/ToolboxAPIClientTests.xcscheme deleted file mode 100644 index f965e5f..0000000 --- a/.swiftpm/xcode/xcshareddata/xcschemes/ToolboxAPIClientTests.xcscheme +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/Sources/ToolboxAPIClient/BaseNetworkWorker.swift b/Sources/ToolboxAPIClient/BaseNetworkWorker.swift index 5e558f4..a4d1714 100644 --- a/Sources/ToolboxAPIClient/BaseNetworkWorker.swift +++ b/Sources/ToolboxAPIClient/BaseNetworkWorker.swift @@ -8,8 +8,10 @@ import Foundation import Combine -public class BaseNetworkWorker where T: Codable { +public class BaseNetworkWorker where T: Codable, E: Codable { private var targetType: TargetType + private let validStatusCode: [Int] = [200, 201] + private let invalidStatusCode: [Int] = [401, 404] public init(target: TargetType) { self.targetType = target @@ -52,6 +54,9 @@ public class BaseNetworkWorker where T: Codable { } public func urlRequest(contentBody: T? = nil) async throws -> T? { + // Decoder + let decoder = JSONDecoder() + // set route with base and path var urlRequest = URLRequest(url: finalUrl) @@ -67,12 +72,33 @@ public class BaseNetworkWorker where T: Codable { if let httpBody = contentBody { let jsonEncoder = JSONEncoder() jsonEncoder.outputFormatting = .prettyPrinted - let data = try? jsonEncoder.encode(httpBody) - urlRequest.httpBody = data + let bodyData = try? jsonEncoder.encode(httpBody) + urlRequest.httpBody = bodyData + } + + let (data, response) = try await URLSession.shared.data(for: urlRequest) + + guard let httpResponse = response as? HTTPURLResponse else { + throw APIErrors.invalidResponse + } + + guard !invalidStatusCode.contains(httpResponse.statusCode) else { + switch httpResponse.statusCode { + case 401: + throw APIErrors.authenticationError + case 404: + throw APIErrors.notFound + default: + let error: E = try decoder.decode(E.self, from: data) + throw APIErrors.serverError(error: error) + } + } + + guard validStatusCode.contains(httpResponse.statusCode) else { + let error: E = try decoder.decode(E.self, from: data) + throw APIErrors.serverError(error: error) } - let (data, _) = try await URLSession.shared.data(for: urlRequest) - let decoder = JSONDecoder() return try decoder.decode(T?.self, from: data) } } diff --git a/Sources/ToolboxAPIClient/Errors.swift b/Sources/ToolboxAPIClient/Errors.swift new file mode 100644 index 0000000..adade91 --- /dev/null +++ b/Sources/ToolboxAPIClient/Errors.swift @@ -0,0 +1,19 @@ +// +// File.swift +// +// +// Created by José Neto on 12/03/2023. +// + +import Foundation + +public enum APIErrors: Error, Equatable { + public static func == (lhs: APIErrors, rhs: APIErrors) -> Bool { + lhs.localizedDescription == rhs.localizedDescription + } + + case notFound + case invalidResponse + case authenticationError + case serverError(error: Codable) +} diff --git a/Tests/ToolboxAPIClientTests/Network/Story/Errors/Errors.swift b/Tests/ToolboxAPIClientTests/Network/Story/Errors/Errors.swift new file mode 100644 index 0000000..a83e69a --- /dev/null +++ b/Tests/ToolboxAPIClientTests/Network/Story/Errors/Errors.swift @@ -0,0 +1,23 @@ +// +// File.swift +// +// +// Created by José Neto on 12/03/2023. +// + +import Foundation + +struct APIReason: Codable { + let error: Bool + let reason: String +} + +class APIError: Codable { + let errorCode: Int + let reason: APIReason + + init(errorCode: String, reason: APIReason) { + self.errorCode = Int(errorCode) ?? 0 + self.reason = reason + } +} diff --git a/Tests/ToolboxAPIClientTests/Network/Story/Manager/LoginManagerAPI.swift b/Tests/ToolboxAPIClientTests/Network/Story/Manager/LoginManagerAPI.swift index c988179..9cae54d 100644 --- a/Tests/ToolboxAPIClientTests/Network/Story/Manager/LoginManagerAPI.swift +++ b/Tests/ToolboxAPIClientTests/Network/Story/Manager/LoginManagerAPI.swift @@ -9,17 +9,21 @@ import Foundation import ToolboxAPIClient public class LoginManagerAPI: LoginRequestable { + public func notFound() async throws { + _ = try await BaseNetworkWorker(target: LoginTarget.notFound).urlRequest() + } + public func login(email: String, password: String) async throws -> LoginDto? { let login: LoginDto = LoginDto(email: email, password: password, token: nil) - return try await BaseNetworkWorker(target: LoginTarget.login).urlRequest(contentBody: login) + return try await BaseNetworkWorker(target: LoginTarget.login).urlRequest(contentBody: login) } public func createUser(email: String, password: String) async throws -> LoginDto? { let login: LoginDto = LoginDto(email: email, password: password, token: nil) - return try await BaseNetworkWorker(target: LoginTarget.createUser).urlRequest(contentBody: login) + return try await BaseNetworkWorker(target: LoginTarget.createUser).urlRequest(contentBody: login) } public func me() async throws -> UserDto? { - try await BaseNetworkWorker(target: LoginTarget.me).urlRequest() + try await BaseNetworkWorker(target: LoginTarget.me).urlRequest() } } diff --git a/Tests/ToolboxAPIClientTests/Network/Story/Targets/LoginTarget.swift b/Tests/ToolboxAPIClientTests/Network/Story/Targets/LoginTarget.swift index 147f7cf..6e1da57 100644 --- a/Tests/ToolboxAPIClientTests/Network/Story/Targets/LoginTarget.swift +++ b/Tests/ToolboxAPIClientTests/Network/Story/Targets/LoginTarget.swift @@ -12,12 +12,14 @@ public protocol LoginRequestable { func createUser(email: String, password: String) async throws -> LoginDto? func login(email: String, password: String) async throws -> LoginDto? func me() async throws -> UserDto? + func notFound() async throws } public enum LoginTarget { case createUser case login case me + case notFound } extension LoginTarget: TargetType { @@ -40,6 +42,8 @@ extension LoginTarget: TargetType { return "login" case .me: return "me" + case .notFound: + return "notfound" } } @@ -51,6 +55,8 @@ extension LoginTarget: TargetType { return .post case .me: return .get + case .notFound: + return .get } } diff --git a/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift b/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift index b849c84..13c3ff2 100644 --- a/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift +++ b/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift @@ -11,8 +11,8 @@ import Combine @testable import ToolboxAPIClient class app_zeneto_api_moduleTests: XCTestCase { - let expectation = XCTestExpectation(description: "CREATE AND LOGIN") - let timeout: TimeInterval = 5.0 + var expectation = XCTestExpectation(description: "CREATE AND LOGIN") + let timeout: TimeInterval = 15.0 var email: String! var password: String! @@ -54,7 +54,49 @@ class app_zeneto_api_moduleTests: XCTestCase { let me = try await userWorker.me() XCTAssertNotNil(me) XCTAssertEqual(email, me?.email) - + + defaults.removeObject(forKey: "token") + defaults.synchronize() + } + + func testErrorLoginUser() throws { + let userWorker = LoginManagerAPI() + expectation = expectation(description: "error login") + // login user + Task { + do { + _ = try await userWorker.me() + } catch { + print(error.localizedDescription) + let exception = error as? APIErrors + XCTAssertNotNil(exception) + XCTAssertEqual(exception, APIErrors.authenticationError) + } + + expectation.fulfill() + } + + waitForExpectations(timeout: timeout) + } + + func testNotFound() throws { + let userWorker = LoginManagerAPI() + expectation = expectation(description: "error login") + // login user + Task { + do { + _ = try await userWorker.notFound() + } catch { + print(error.localizedDescription) + let exception = error as? APIErrors + XCTAssertNotNil(exception) + XCTAssertEqual(exception, APIErrors.notFound) + } + + expectation.fulfill() + } + + waitForExpectations(timeout: timeout) } }