From 5427e6ef15c082a12344b7f17e9958d8cb20bdfc Mon Sep 17 00:00:00 2001 From: tauseefmohammed2 <35351464+tauseefmohammed2@users.noreply.github.com> Date: Fri, 17 May 2024 01:18:16 -0500 Subject: [PATCH] test: added firebase authentication test --- .../Services/FirebaseProtocols.swift | 16 +++++++ .../Services/FirebaseServicesExtensions.swift | 30 +++++++++++++ .../AuthViewModelTests.swift | 23 ++++++++++ SE491GroupProjectTests/MockFirebaseAuth.swift | 45 +++++++++++++++++++ 4 files changed, 114 insertions(+) create mode 100644 SE491GroupProject/Services/FirebaseProtocols.swift create mode 100644 SE491GroupProject/Services/FirebaseServicesExtensions.swift create mode 100644 SE491GroupProjectTests/AuthViewModelTests.swift create mode 100644 SE491GroupProjectTests/MockFirebaseAuth.swift diff --git a/SE491GroupProject/Services/FirebaseProtocols.swift b/SE491GroupProject/Services/FirebaseProtocols.swift new file mode 100644 index 0000000..d636fc2 --- /dev/null +++ b/SE491GroupProject/Services/FirebaseProtocols.swift @@ -0,0 +1,16 @@ +// FirebaseProtocols.swift +import Firebase +import FirebaseFirestoreSwift + +protocol FirebaseAuthenticating { + func signIn(withEmail email: String, password: String) async throws -> FirebaseAuth.User + func createUser(withEmail email: String, password: String) async throws -> FirebaseAuth.User + func signOut() throws + func sendPasswordReset(withEmail email: String, completion: @escaping (Error?) -> Void) + func delete(user: FirebaseAuth.User, completion: @escaping (Error?) -> Void) +} + +protocol FirestoreHandling { + func setData(for user: User, in collection: String) async throws + func fetchUser(uid: String, from collection: String) async throws -> User? +} \ No newline at end of file diff --git a/SE491GroupProject/Services/FirebaseServicesExtensions.swift b/SE491GroupProject/Services/FirebaseServicesExtensions.swift new file mode 100644 index 0000000..1dd868b --- /dev/null +++ b/SE491GroupProject/Services/FirebaseServicesExtensions.swift @@ -0,0 +1,30 @@ +// FirebaseServicesExtensions.swift +import Firebase + +extension Auth: FirebaseAuthenticating { + func signIn(withEmail email: String, password: String) async throws -> FirebaseAuth.User { + let result = try await signIn(withEmail: email, password: password) + return result.user + } + + func createUser(withEmail email: String, password: String) async throws -> FirebaseAuth.User { + let result = try await createUser(withEmail: email, password: password) + return result.user + } + + func delete(user: FirebaseAuth.User, completion: @escaping (Error?) -> Void) { + user.delete(completion: completion) + } +} + +extension Firestore: FirestoreHandling { + func setData(for user: User, in collection: String) async throws { + let encodedUser = try Firestore.Encoder().encode(user) + let _ = try await collection(collection).document(user.id).setData(encodedUser) + } + + func fetchUser(uid: String, from collection: String) async throws -> User? { + let snapshot = try await collection(collection).document(uid).getDocument() + return try snapshot.data(as: User.self) + } +} \ No newline at end of file diff --git a/SE491GroupProjectTests/AuthViewModelTests.swift b/SE491GroupProjectTests/AuthViewModelTests.swift new file mode 100644 index 0000000..fd7a282 --- /dev/null +++ b/SE491GroupProjectTests/AuthViewModelTests.swift @@ -0,0 +1,23 @@ +import XCTest +@testable import SE491GroupProject + +final class AuthViewModelTests: XCTestCase { + private var viewModel: AuthViewModel! + private var mockAuth: MockAuth! + + override func setUp() { + super.setUp() + mockAuth = MockAuth() + viewModel = AuthViewModel(auth: mockAuth) + } + + func testSignInSuccess() async { + mockAuth.mockedUser = FirebaseAuth.User(uid: "LEcivUowvvYab8mE8e3s5sXJbPR2", email: "admin@gmail.com") // Assuming FirebaseAuth.User has this initializer + do { + let user = try await viewModel.signIn(withEmail: "admin@gmail.com", password: "123456789") + XCTAssertEqual(user.email, "admin@gmail.com") + } catch { + XCTFail("SignIn should succeed") + } + } +} \ No newline at end of file diff --git a/SE491GroupProjectTests/MockFirebaseAuth.swift b/SE491GroupProjectTests/MockFirebaseAuth.swift new file mode 100644 index 0000000..bdc59f1 --- /dev/null +++ b/SE491GroupProjectTests/MockFirebaseAuth.swift @@ -0,0 +1,45 @@ +// MockFirebaseAuth.swift +import Firebase + +class MockAuth: FirebaseAuthenticating { + var shouldReturnError = false + var mockedUser: FirebaseAuth.User? + + func signIn(withEmail email: String, password: String) async throws -> FirebaseAuth.User { + if let user = mockedUser, !shouldReturnError { + return user + } else { + throw NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "Mock: Failed to sign in"]) + } + } + + func createUser(withEmail email: String, password: String) async throws -> FirebaseAuth.User { + if let user = mockedUser, !shouldReturnError { + return user + } else { + throw NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "Mock: Failed to create user"]) + } + } + + func signOut() throws { + if shouldReturnError { + throw NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "Mock: Failed to sign out"]) + } + } + + func sendPasswordReset(withEmail email: String, completion: @escaping (Error?) -> Void) { + if shouldReturnError { + completion(NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "Mock: Failed to send password reset email"])) + } else { + completion(nil) + } + } + + func delete(user: FirebaseAuth.User, completion: @escaping (Error?) -> Void) { + if shouldReturnError { + completion(NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "Mock: Failed to delete user"])) + } else { + completion(nil) + } + } +} \ No newline at end of file