diff --git a/Networking/Sources/Networking/Constants.swift b/Networking/Sources/Networking/Constants.swift index 92fa6d7..b77940b 100644 --- a/Networking/Sources/Networking/Constants.swift +++ b/Networking/Sources/Networking/Constants.swift @@ -24,7 +24,7 @@ enum Constants { return url }() - + static let firebaseKey: String = { return "AIzaSyB0UczrurqM1STyI8tvx4QZVTyQVw4UJ7Q" }() diff --git a/Networking/Sources/Networking/Requests/FirebaseLoginRequest.swift b/Networking/Sources/Networking/Requests/FirebaseLoginRequest.swift new file mode 100644 index 0000000..33bc34b --- /dev/null +++ b/Networking/Sources/Networking/Requests/FirebaseLoginRequest.swift @@ -0,0 +1,48 @@ +import Foundation + +// MARK: - FirebaseLoginResponse +public struct FirebaseLoginResponse: Codable { + let kind, localID, email, displayName: String + let idToken: String + let registered: Bool + let refreshToken, expiresIn: String +} + +// MARK: - FirebaseLoginRequest +public struct FirebaseLoginRequest: RequestType { + public typealias ResponseType = FirebaseLoginResponse + + private let email: String + private let password: String + + public init(email: String, password: String) { + self.email = email + self.password = password + } + + public var baseUrl: URL { Constants.firebaseAuth } + public var path: String { "/v1/accounts:signInWithPassword" } + public var method: String { "POST" } + + public var queryParameters: [String: String] { + [ + "key": Constants.firebaseKey + ] + } + + public var headers: [String: String] { + [ "Content-Type": "application/json" ] + } + + public var requestBody: [String: Any] { + [ + "email": email, + "password": password, + "returnSecureToken": true + ] + } + + public let responseDecoder: (Data) throws -> FirebaseLoginResponse = { data in + try JSONDecoder().decode(ResponseType.self, from: data) + } +} diff --git a/Networking/Sources/Networking/Requests/MealCategoriesRequest.swift b/Networking/Sources/Networking/Requests/MealCategoriesRequest.swift index fd9d17c..b6d10f3 100644 --- a/Networking/Sources/Networking/Requests/MealCategoriesRequest.swift +++ b/Networking/Sources/Networking/Requests/MealCategoriesRequest.swift @@ -10,7 +10,7 @@ public struct Category: Decodable { let categoryId, categoryTitle: String let categoryThumb: String let categoryDescription: String - + enum CodingKeys: String, CodingKey { case categoryId = "idCategory" case categoryTitle = "strCategory" @@ -21,7 +21,7 @@ public struct Category: Decodable { // MARK: - MealCategoriesRequest public struct MealCategoriesRequest: RequestType { - + public typealias ResponseType = MealCategoriesResponse public init() {} diff --git a/Networking/Sources/Networking/Requests/RegisterRequest.swift b/Networking/Sources/Networking/Requests/RegisterRequest.swift index 708d145..ac781f7 100644 --- a/Networking/Sources/Networking/Requests/RegisterRequest.swift +++ b/Networking/Sources/Networking/Requests/RegisterRequest.swift @@ -19,7 +19,7 @@ public struct RegisterRequest: RequestType { private let email: String private let password: String private let returnSecureToken: Bool - + public init(email: String, password: String, returnSecureToken: Bool = true) { self.email = email self.password = password diff --git a/Networking/Tests/NetworkingTests/Requests/FirebaseLoginRequestTest.swift b/Networking/Tests/NetworkingTests/Requests/FirebaseLoginRequestTest.swift new file mode 100644 index 0000000..1dec64a --- /dev/null +++ b/Networking/Tests/NetworkingTests/Requests/FirebaseLoginRequestTest.swift @@ -0,0 +1,69 @@ +import XCTest +@testable import Networking + +final class FirebaseLoginRequestTests: XCTestCase { + + func testFirebaseLoginRequestProperties() { + // Given + let email = "test@example.com" + let password = "secretpassword" + let loginRequest = FirebaseLoginRequest(email: email, password: password) + + // Then + XCTAssertEqual(loginRequest.baseUrl, Constants.firebaseAuth) + XCTAssertEqual(loginRequest.path, "/v1/accounts:signInWithPassword") + XCTAssertEqual(loginRequest.method, "POST") + XCTAssertEqual(loginRequest.queryParameters, [ + "key": Constants.fireBaseAuthKey + ]) + XCTAssertEqual(loginRequest.headers, [ + "Content-Type": "application/json" + ]) + } + + func testFirebaseLoginRequestBody() { + // Given + let email = "test@example.com" + let password = "secretpassword" + let loginRequest = FirebaseLoginRequest(email: email, password: password) + + // When + let requestBody = loginRequest.requestBody + + // Then + XCTAssertEqual(requestBody["email"] as? String, email) + XCTAssertEqual(requestBody["password"] as? String, password) + XCTAssertEqual(requestBody["returnSecureToken"] as? Bool, true) + } + + func testFirebaseLoginRequestResponseDecoder() throws { + // Given + let loginResponseAsString = """ + { + "kind": "identitytoolkit#VerifyPasswordResponse", + "localId": "1234567890", + "email": "test@example.com", + "displayName": "John Doe", + "idToken": "abcdefghijk", + "registered": true, + "refreshToken": "qrstuvwxyz", + "expiresIn": "3600" + } + """ + let loginRequest = FirebaseLoginRequest(email: "test@example.com", password: "secretpassword") + + // When + let loginResponseData = try XCTUnwrap(loginResponseAsString.data(using: .utf8)) + guard let loginResponse = try? loginRequest.responseDecoder(loginResponseData) else { return } + // Then + XCTAssertNotNil(loginResponse) + XCTAssertEqual(loginResponse.kind, "identitytoolkit#VerifyPasswordResponse") + XCTAssertEqual(loginResponse.localID, "1234567890") + XCTAssertEqual(loginResponse.email, "test@example.com") + XCTAssertEqual(loginResponse.displayName, "John Doe") + XCTAssertEqual(loginResponse.idToken, "abcdefghijk") + XCTAssertEqual(loginResponse.registered, true) + XCTAssertEqual(loginResponse.refreshToken, "qrstuvwxyz") + XCTAssertEqual(loginResponse.expiresIn, "3600") + } +} diff --git a/Networking/Tests/NetworkingTests/Requests/MealCategoriesRequestTests.swift b/Networking/Tests/NetworkingTests/Requests/MealCategoriesRequestTests.swift index 0792dd9..953c384 100644 --- a/Networking/Tests/NetworkingTests/Requests/MealCategoriesRequestTests.swift +++ b/Networking/Tests/NetworkingTests/Requests/MealCategoriesRequestTests.swift @@ -4,24 +4,24 @@ import XCTest final class MealCategoriesRequestTests: XCTestCase { // MARK: Properties - + private var sut: MealCategoriesRequest! - + // MARK: - Lifecycle - + override func setUp() { sut = MealCategoriesRequest() } - + // MARK: - Tests - + func testMealCategoriesRequestProperties() { // Then XCTAssertEqual(sut.baseUrl, Constants.theMealDB) XCTAssertEqual(sut.path, "categories.php") XCTAssertEqual(sut.method, "GET") } - + func testMealCategoriesResponseDecoder() throws { // Given let mealCategoriesResponseAsString = """ @@ -36,11 +36,11 @@ final class MealCategoriesRequestTests: XCTestCase { ] } """ - + // When let mealCategoriesResponseData = try XCTUnwrap(mealCategoriesResponseAsString.data(using: .utf8)) let mealCategoriesResponse = try? sut.responseDecoder(mealCategoriesResponseData) - + // Then XCTAssertNotNil(mealCategoriesResponse) XCTAssertEqual(mealCategoriesResponse?.categories.count, 1) diff --git a/Networking/Tests/NetworkingTests/Requests/RegisterRequestTests.swift b/Networking/Tests/NetworkingTests/Requests/RegisterRequestTests.swift index 3efe68e..43cacc7 100644 --- a/Networking/Tests/NetworkingTests/Requests/RegisterRequestTests.swift +++ b/Networking/Tests/NetworkingTests/Requests/RegisterRequestTests.swift @@ -4,7 +4,7 @@ import XCTest final class RegisterRequestTests: XCTestCase { // MARK: - Tests - + func testRegisterRequestProperties() { // Given let email = "test@example.com" @@ -16,7 +16,7 @@ final class RegisterRequestTests: XCTestCase { XCTAssertEqual(registerRequest.path, "/accounts:signInWithPassword?key=\(Constants.firebaseKey)") XCTAssertEqual(registerRequest.method, "POST") } - + func testRegisterRequestResponseDecoder() throws { // Given let registerResponseAsString = """