import XCTest @testable import iosApp import ComposeApp @MainActor final class LoginViewModelTests: XCTestCase { var sut: LoginViewModel! override func setUp() { super.setUp() sut = LoginViewModel() } override func tearDown() { sut = nil super.tearDown() } // MARK: - Initialization Tests func testInitialState() { // Then XCTAssertEqual(sut.username, "") XCTAssertEqual(sut.password, "") XCTAssertFalse(sut.isLoading) XCTAssertNil(sut.errorMessage) XCTAssertFalse(sut.isAuthenticated) XCTAssertFalse(sut.isVerified) XCTAssertNil(sut.currentUser) } // MARK: - Validation Tests func testLoginWithEmptyUsername() { // Given sut.username = "" sut.password = "password123" // When sut.login() // Then XCTAssertEqual(sut.errorMessage, "Username is required") XCTAssertFalse(sut.isLoading) } func testLoginWithEmptyPassword() { // Given sut.username = "testuser" sut.password = "" // When sut.login() // Then XCTAssertEqual(sut.errorMessage, "Password is required") XCTAssertFalse(sut.isLoading) } func testLoginWithValidCredentials() { // Given sut.username = "testuser" sut.password = "password123" // When sut.login() // Then XCTAssertTrue(sut.isLoading || sut.errorMessage != nil || sut.isAuthenticated) } // MARK: - Error Handling Tests func testCleanErrorMessageRemovesJSONStructures() { // Given let dirtyMessage = "Error: {\"detail\": \"Invalid credentials\"}" // When - We can't directly test private method, but we can test the behavior sut.errorMessage = dirtyMessage // Then - Error message should be set (even if not cleaned in this test) XCTAssertNotNil(sut.errorMessage) } func testClearError() { // Given sut.errorMessage = "Test error" // When sut.clearError() // Then XCTAssertNil(sut.errorMessage) } // MARK: - Logout Tests func testLogout() { // Given sut.isAuthenticated = true sut.isVerified = true sut.username = "testuser" sut.password = "password" sut.errorMessage = "Test error" // When sut.logout() // Then XCTAssertFalse(sut.isAuthenticated) XCTAssertFalse(sut.isVerified) XCTAssertNil(sut.currentUser) XCTAssertEqual(sut.username, "") XCTAssertEqual(sut.password, "") XCTAssertNil(sut.errorMessage) } // MARK: - State Management Tests func testLoadingStateChanges() { // Given let initialLoadingState = sut.isLoading // When sut.login() // Then - Loading state should change (either true during loading or false after quick failure) XCTAssertTrue(sut.isLoading != initialLoadingState || sut.errorMessage != nil) } }