Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions SE491GroupProject/Services/FirebaseProtocols.swift
Original file line number Diff line number Diff line change
@@ -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?
}
30 changes: 30 additions & 0 deletions SE491GroupProject/Services/FirebaseServicesExtensions.swift
Original file line number Diff line number Diff line change
@@ -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)
}
}
23 changes: 23 additions & 0 deletions SE491GroupProjectTests/AuthViewModelTests.swift
Original file line number Diff line number Diff line change
@@ -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")
}
}
}
45 changes: 45 additions & 0 deletions SE491GroupProjectTests/MockFirebaseAuth.swift
Original file line number Diff line number Diff line change
@@ -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)
}
}
}