From 52591dbb08c12ff1d1d67491701205c885b1ecf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Neto?= Date: Sun, 7 Feb 2021 21:55:25 -0300 Subject: [PATCH 1/2] post support --- .../ToolboxAPIClient_Package.xml | 11 +++ .idea/vcs.xml | 6 ++ .idea/workspace.xml | 96 +++++++++++++++++++ .idea/xcode.xml | 4 + ...58ED545A-31BB-4484-A7DB-7CF3A75F662D.plist | 22 +++++ .../Info.plist | 33 +++++++ .../xcschemes/ToolboxAPIClient.xcscheme | 92 ++++++++++++++++++ Sources/ToolboxAPIClient/Endpoint.swift | 11 ++- .../Extensions/Endpoint+Extension.swift | 2 +- Sources/ToolboxAPIClient/HttpMethodEnum.swift | 16 ++++ Sources/ToolboxAPIClient/NetworkManager.swift | 30 +++++- .../NetworkManagerProtocol.swift | 6 +- .../Users/UserEndpoint+Extension.swift | 4 + .../Users/UserNetworkManagerProtocol.swift | 7 +- .../Tests/app_zeneto_api_moduleTests.swift | 37 ++++++- .../UserNetworkManager.swift | 17 ++-- 16 files changed, 373 insertions(+), 21 deletions(-) create mode 100644 .idea/runConfigurations/ToolboxAPIClient_Package.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml create mode 100644 .idea/xcode.xml create mode 100644 .swiftpm/xcode/xcshareddata/xcbaselines/ToolboxAPIClientTests.xcbaseline/58ED545A-31BB-4484-A7DB-7CF3A75F662D.plist create mode 100644 .swiftpm/xcode/xcshareddata/xcbaselines/ToolboxAPIClientTests.xcbaseline/Info.plist create mode 100644 .swiftpm/xcode/xcshareddata/xcschemes/ToolboxAPIClient.xcscheme create mode 100644 Sources/ToolboxAPIClient/HttpMethodEnum.swift diff --git a/.idea/runConfigurations/ToolboxAPIClient_Package.xml b/.idea/runConfigurations/ToolboxAPIClient_Package.xml new file mode 100644 index 0000000..ed893b9 --- /dev/null +++ b/.idea/runConfigurations/ToolboxAPIClient_Package.xml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..dbcde65 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1612730248592 + + + + + + + + file://$PROJECT_DIR$/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift + 102 + + + file://$PROJECT_DIR$/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift + 108 + + + + + \ No newline at end of file diff --git a/.idea/xcode.xml b/.idea/xcode.xml new file mode 100644 index 0000000..b55a18c --- /dev/null +++ b/.idea/xcode.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.swiftpm/xcode/xcshareddata/xcbaselines/ToolboxAPIClientTests.xcbaseline/58ED545A-31BB-4484-A7DB-7CF3A75F662D.plist b/.swiftpm/xcode/xcshareddata/xcbaselines/ToolboxAPIClientTests.xcbaseline/58ED545A-31BB-4484-A7DB-7CF3A75F662D.plist new file mode 100644 index 0000000..3aa66df --- /dev/null +++ b/.swiftpm/xcode/xcshareddata/xcbaselines/ToolboxAPIClientTests.xcbaseline/58ED545A-31BB-4484-A7DB-7CF3A75F662D.plist @@ -0,0 +1,22 @@ + + + + + classNames + + app_zeneto_api_moduleTests + + testPerformanceExample() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 2.0939e-05 + baselineIntegrationDisplayName + Local Baseline + + + + + + diff --git a/.swiftpm/xcode/xcshareddata/xcbaselines/ToolboxAPIClientTests.xcbaseline/Info.plist b/.swiftpm/xcode/xcshareddata/xcbaselines/ToolboxAPIClientTests.xcbaseline/Info.plist new file mode 100644 index 0000000..67d827f --- /dev/null +++ b/.swiftpm/xcode/xcshareddata/xcbaselines/ToolboxAPIClientTests.xcbaseline/Info.plist @@ -0,0 +1,33 @@ + + + + + runDestinationsByUUID + + 58ED545A-31BB-4484-A7DB-7CF3A75F662D + + localComputer + + busSpeedInMHz + 400 + cpuCount + 1 + cpuKind + 6-Core Intel Core i7 + cpuSpeedInMHz + 2600 + logicalCPUCoresPerPackage + 12 + modelCode + MacBookPro15,1 + physicalCPUCoresPerPackage + 6 + platformIdentifier + com.apple.platform.macosx + + targetArchitecture + x86_64 + + + + diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/ToolboxAPIClient.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/ToolboxAPIClient.xcscheme new file mode 100644 index 0000000..55a9cc3 --- /dev/null +++ b/.swiftpm/xcode/xcshareddata/xcschemes/ToolboxAPIClient.xcscheme @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sources/ToolboxAPIClient/Endpoint.swift b/Sources/ToolboxAPIClient/Endpoint.swift index 71ffa92..2f5077d 100644 --- a/Sources/ToolboxAPIClient/Endpoint.swift +++ b/Sources/ToolboxAPIClient/Endpoint.swift @@ -6,13 +6,20 @@ import Foundation public struct Endpoint { public var path: String public var queryItems: [URLQueryItem] = [] - + public var method: HttpMethodEnum = .get + public init(path: String) { self.path = path } + + public init(path: String, method: HttpMethodEnum) { + self.path = path + self.method = method + } public init(path: String, queryItems: [URLQueryItem]) { self.path = path self.queryItems = queryItems } -} \ No newline at end of file +} + diff --git a/Sources/ToolboxAPIClient/Extensions/Endpoint+Extension.swift b/Sources/ToolboxAPIClient/Extensions/Endpoint+Extension.swift index 691d984..5f77d80 100644 --- a/Sources/ToolboxAPIClient/Extensions/Endpoint+Extension.swift +++ b/Sources/ToolboxAPIClient/Extensions/Endpoint+Extension.swift @@ -16,6 +16,6 @@ extension Endpoint { return url } public var headers: [String: Any] { - ["app-id": "app.zeneto.zeneto-api-module"] + ["Content-Type": "application/json", "cache-control": "no-cache"] } } diff --git a/Sources/ToolboxAPIClient/HttpMethodEnum.swift b/Sources/ToolboxAPIClient/HttpMethodEnum.swift new file mode 100644 index 0000000..03c752f --- /dev/null +++ b/Sources/ToolboxAPIClient/HttpMethodEnum.swift @@ -0,0 +1,16 @@ +// +// HttpMethodEnum.swift +// +// +// Created by Zé on 07/02/21. +// + +import Foundation + +public enum HttpMethodEnum: String { + case get = "GET" + case post = "POST" + case put = "PUT" + case delete = "DELETE" + case patch = "PATCH" +} diff --git a/Sources/ToolboxAPIClient/NetworkManager.swift b/Sources/ToolboxAPIClient/NetworkManager.swift index 0392eec..840d9b3 100644 --- a/Sources/ToolboxAPIClient/NetworkManager.swift +++ b/Sources/ToolboxAPIClient/NetworkManager.swift @@ -6,12 +6,36 @@ import Combine @available(OSX 10.15, *) public final class NetworkManager: NetworkManagerProtocol { - public init() { } + + public func get(type: T.Type, endPoint: Endpoint) -> AnyPublisher { + urlRequest(type: T.self, httpverb: endPoint.method.rawValue, httpBody: nil, url: endPoint.url, headers: endPoint.headers) + } + + public func post(type: T.Type, body: T, endPoint: Endpoint) -> AnyPublisher where T: Codable { + let jsonEncoder = JSONEncoder() + jsonEncoder.outputFormatting = .prettyPrinted + let data = try? jsonEncoder.encode(body) + return urlRequest(type: T.self, httpverb: endPoint.method.rawValue, httpBody: data, url: endPoint.url, headers: endPoint.headers) + } + + public func put(type: T.Type, url: URL, headers: Headers) -> AnyPublisher where T: Decodable { + Empty(completeImmediately: true).eraseToAnyPublisher() + } + + public func delete(type: T.Type, url: URL, headers: Headers) -> AnyPublisher where T: Decodable { + Empty(completeImmediately: true).eraseToAnyPublisher() + } + + public func patch(type: T.Type, url: URL, headers: Headers) -> AnyPublisher where T: Decodable { + Empty(completeImmediately: true).eraseToAnyPublisher() + } - public func get(type: T.Type, url: URL, headers: Headers) -> AnyPublisher { + private func urlRequest(type: T.Type, httpverb: String, httpBody: Data?, url: URL, headers: Headers) -> AnyPublisher { var urlRequest = URLRequest(url: url) + urlRequest.httpMethod = httpverb + urlRequest.httpBody = httpBody headers.forEach { (key, value) in if let value = value as? String { @@ -21,7 +45,7 @@ public final class NetworkManager: NetworkManagerProtocol { return URLSession.shared.dataTaskPublisher(for: urlRequest) .map { $0.data } - .decode(type: T.self, decoder: JSONDecoder()) + .decode(type: T?.self, decoder: JSONDecoder()) .eraseToAnyPublisher() } } diff --git a/Sources/ToolboxAPIClient/NetworkManagerProtocol.swift b/Sources/ToolboxAPIClient/NetworkManagerProtocol.swift index 9198b16..69def2d 100644 --- a/Sources/ToolboxAPIClient/NetworkManagerProtocol.swift +++ b/Sources/ToolboxAPIClient/NetworkManagerProtocol.swift @@ -8,5 +8,9 @@ import Combine public protocol NetworkManagerProtocol: class { typealias Headers = [String: Any] - func get(type: T.Type, url: URL, headers: Headers) -> AnyPublisher where T: Decodable + func get(type: T.Type, endPoint: Endpoint) -> AnyPublisher where T: Decodable + func post(type: T.Type, body: T, endPoint: Endpoint) -> AnyPublisher where T: Codable + func put(type: T.Type, url: URL, headers: Headers) -> AnyPublisher where T: Decodable + func delete(type: T.Type, url: URL, headers: Headers) -> AnyPublisher where T: Decodable + func patch(type: T.Type, url: URL, headers: Headers) -> AnyPublisher where T: Decodable } diff --git a/Tests/ToolboxAPIClientTests/Network/Users/UserEndpoint+Extension.swift b/Tests/ToolboxAPIClientTests/Network/Users/UserEndpoint+Extension.swift index 589468d..2d2a66d 100644 --- a/Tests/ToolboxAPIClientTests/Network/Users/UserEndpoint+Extension.swift +++ b/Tests/ToolboxAPIClientTests/Network/Users/UserEndpoint+Extension.swift @@ -16,4 +16,8 @@ extension Endpoint { static func user(id: String) -> Self { Endpoint(path: "/users/\(id)") } + + static func createUser(user: User) -> Self { + Endpoint(path: "/c706cbfe-6550-4d3a-9d9b-ae19d1425245", method: .post) + } } diff --git a/Tests/ToolboxAPIClientTests/Network/Users/UserNetworkManagerProtocol.swift b/Tests/ToolboxAPIClientTests/Network/Users/UserNetworkManagerProtocol.swift index 5a20daf..06c0ec1 100644 --- a/Tests/ToolboxAPIClientTests/Network/Users/UserNetworkManagerProtocol.swift +++ b/Tests/ToolboxAPIClientTests/Network/Users/UserNetworkManagerProtocol.swift @@ -9,7 +9,8 @@ import ToolboxAPIClient protocol UserNetworkManagerProtocol: class { var networkController: NetworkManagerProtocol { get } - func getUsers() -> AnyPublisher - func getUsers(count: Int) -> AnyPublisher - func getUser(id: String) -> AnyPublisher + func getUsers() -> AnyPublisher + func getUsers(count: Int) -> AnyPublisher + func getUser(id: String) -> AnyPublisher + func createUser(user: User) -> AnyPublisher } diff --git a/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift b/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift index ba0f870..511a426 100644 --- a/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift +++ b/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift @@ -12,7 +12,7 @@ import Combine @testable import ToolboxAPIClient class app_zeneto_api_moduleTests: XCTestCase { let expectation = XCTestExpectation(description: "GET USER DATA FROM MOCKY.IO") - let timeout: TimeInterval = 2.0 + let timeout: TimeInterval = 5.0 static var allTests = [ ("getUsers", testGetUser), @@ -44,8 +44,8 @@ class app_zeneto_api_moduleTests: XCTestCase { self?.expectation.fulfill() break } - }, receiveValue: { (value: Users) in - guard let users = value.data else { + }, receiveValue: { (value: Users?) in + guard let users = value?.data else { XCTFail() return } @@ -74,8 +74,8 @@ class app_zeneto_api_moduleTests: XCTestCase { self?.expectation.fulfill() break } - }, receiveValue: { (value: Users) in - guard let users = value.data else { + }, receiveValue: { (value: Users?) in + guard let users = value?.data else { XCTFail() return } @@ -85,6 +85,33 @@ class app_zeneto_api_moduleTests: XCTestCase { wait(for: [expectation], timeout: timeout) } + func testCreateUser() throws { + let networkManager = NetworkManager() + let userManager = UserNetworkManager(networkController: networkManager) + var subscriptions = Set() + + let user = User(id: "a94bff9b-d0fc-49ba-9a4f-4f9234d16561", + firstName: "Mackenzie", + lastName: "Sebire", + email: "msebire0@diigo.com") + + userManager.createUser(user: user) + .sink(receiveCompletion: { [weak self] completion in + switch completion { + case let .failure(error): + print("Error API: \(error)") + XCTFail() + case .finished: + self?.expectation.fulfill() + break + } + }, receiveValue: { (value: User?) in + XCTAssertNotNil(value) + }).store(in: &subscriptions) + + wait(for: [expectation], timeout: timeout) + } + func testPerformanceExample() throws { // This is an example of a performance test case. self.measure { diff --git a/Tests/ToolboxAPIClientTests/UserNetworkManager.swift b/Tests/ToolboxAPIClientTests/UserNetworkManager.swift index c5ec89e..a3fabd6 100644 --- a/Tests/ToolboxAPIClientTests/UserNetworkManager.swift +++ b/Tests/ToolboxAPIClientTests/UserNetworkManager.swift @@ -12,18 +12,23 @@ final class UserNetworkManager: UserNetworkManagerProtocol { self.networkController = networkController } - func getUsers() -> AnyPublisher { + func getUsers() -> AnyPublisher { let endpoint = Endpoint.users - return networkController.get(type: Users.self, url: endpoint.url, headers: endpoint.headers) + return networkController.get(type: Users.self, endPoint: endpoint) } - func getUsers(count: Int) -> AnyPublisher { + func getUsers(count: Int) -> AnyPublisher { let endpoint = Endpoint.users(count: count) - return networkController.get(type: Users.self, url: endpoint.url, headers: endpoint.headers) + return networkController.get(type: Users.self, endPoint: endpoint) } - func getUser(id: String) -> AnyPublisher { + func getUser(id: String) -> AnyPublisher { let endpoint = Endpoint.user(id: id) - return networkController.get(type: User.self, url: endpoint.url, headers: endpoint.headers) + return networkController.get(type: User.self, endPoint: endpoint) + } + + func createUser(user: User) -> AnyPublisher { + let endpoint = Endpoint.createUser(user: user) + return networkController.post(type: User.self, body: user, endPoint: endpoint) } } From 66726cca6820087ad6a3420fcdf291b3dd39c2bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Neto?= Date: Sun, 7 Feb 2021 22:09:56 -0300 Subject: [PATCH 2/2] get user by id --- .idea/workspace.xml | 38 ++++++------------- .../Users/UserEndpoint+Extension.swift | 2 +- .../Tests/app_zeneto_api_moduleTests.swift | 33 ++++++++++++---- 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index dbcde65..c153100 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,17 +2,9 @@ - - - - - - - + - - - + + + + + + - + + @@ -77,20 +76,7 @@ - - - - - file://$PROJECT_DIR$/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift - 102 - - - file://$PROJECT_DIR$/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift - 108 - - - + + \ No newline at end of file diff --git a/Tests/ToolboxAPIClientTests/Network/Users/UserEndpoint+Extension.swift b/Tests/ToolboxAPIClientTests/Network/Users/UserEndpoint+Extension.swift index 2d2a66d..526dd5f 100644 --- a/Tests/ToolboxAPIClientTests/Network/Users/UserEndpoint+Extension.swift +++ b/Tests/ToolboxAPIClientTests/Network/Users/UserEndpoint+Extension.swift @@ -14,7 +14,7 @@ extension Endpoint { } static func user(id: String) -> Self { - Endpoint(path: "/users/\(id)") + Endpoint(path: "/c706cbfe-6550-4d3a-9d9b-ae19d1425245/\(id)") } static func createUser(user: User) -> Self { diff --git a/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift b/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift index 511a426..79e9f99 100644 --- a/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift +++ b/Tests/ToolboxAPIClientTests/Tests/app_zeneto_api_moduleTests.swift @@ -17,6 +17,8 @@ class app_zeneto_api_moduleTests: XCTestCase { static var allTests = [ ("getUsers", testGetUser), ("getUsersWithLimit", testGetUserWithLimit), + ("getUsersByID", testGetUserById), + ("createUser", testCreateUser) ] override func setUpWithError() throws { @@ -85,6 +87,29 @@ class app_zeneto_api_moduleTests: XCTestCase { wait(for: [expectation], timeout: timeout) } + func testGetUserById() throws { + let networkManager = NetworkManager() + let userManager = UserNetworkManager(networkController: networkManager) + var subscriptions = Set() + + let id: String = "a94bff9b-d0fc-49ba-9a4f-4f9234d16561" + userManager.getUser(id: id) + .sink(receiveCompletion: { [weak self] completion in + switch completion { + case let .failure(error): + print("Error API: \(error)") + XCTFail() + case .finished: + self?.expectation.fulfill() + break + } + }, receiveValue: { (value: User?) in + XCTAssertNotNil(value) + }).store(in: &subscriptions) + + wait(for: [expectation], timeout: timeout) + } + func testCreateUser() throws { let networkManager = NetworkManager() let userManager = UserNetworkManager(networkController: networkManager) @@ -111,12 +136,4 @@ class app_zeneto_api_moduleTests: XCTestCase { wait(for: [expectation], timeout: timeout) } - - func testPerformanceExample() throws { - // This is an example of a performance test case. - self.measure { - // Put the code you want to measure the time of here. - } - } - }