Files
honeyDueKMP/iosApp/CaseraTests/ErrorMessageParserTests.swift
treyt fc0e0688eb Add comprehensive iOS unit and UI test suites for greenfield test plan
- Create unit tests: DataLayerTests (27 tests for DATA-001–007), DataManagerExtendedTests
  (20 tests for TASK-005, TASK-012, TCOMP-003, THEME-001, QA-002), plus ValidationHelpers,
  TaskMetrics, StringExtensions, DoubleExtensions, DateUtils, DocumentHelpers, ErrorMessageParser
- Create UI tests: AuthenticationTests, PasswordResetTests, OnboardingTests, TaskIntegration,
  ContractorIntegration, ResidenceIntegration, DocumentIntegration, DataLayer, Stability
- Add UI test framework: AuthenticatedTestCase, ScreenObjects, TestFlows, TestAccountManager,
  TestAccountAPIClient, TestDataCleaner, TestDataSeeder
- Add accessibility identifiers to password reset views for UI test support
- Add greenfield test plan CSVs and update automated column for 27 test IDs
- All 297 unit tests pass across 60 suites

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:37:56 -06:00

222 lines
7.6 KiB
Swift

//
// ErrorMessageParserTests.swift
// CaseraTests
//
// Unit tests for ErrorMessageParser error code mapping, network error detection,
// and message parsing logic.
//
import Testing
@testable import Casera
// MARK: - API Error Code Mapping Tests
struct ErrorCodeMappingTests {
@Test func invalidCredentialsCode() {
let result = ErrorMessageParser.parse("error.invalid_credentials")
#expect(result == "Invalid username or password. Please try again.")
}
@Test func invalidTokenCode() {
let result = ErrorMessageParser.parse("error.invalid_token")
#expect(result == "Your session has expired. Please log in again.")
}
@Test func usernameTakenCode() {
let result = ErrorMessageParser.parse("error.username_taken")
#expect(result == "This username is already taken. Please choose another.")
}
@Test func emailTakenCode() {
let result = ErrorMessageParser.parse("error.email_taken")
#expect(result == "This email is already registered. Try logging in instead.")
}
@Test func invalidVerificationCodeCode() {
let result = ErrorMessageParser.parse("error.invalid_verification_code")
#expect(result == "Invalid verification code. Please check and try again.")
}
@Test func verificationCodeExpiredCode() {
let result = ErrorMessageParser.parse("error.verification_code_expired")
#expect(result == "Your verification code has expired. Please request a new one.")
}
@Test func rateLimitExceededCode() {
let result = ErrorMessageParser.parse("error.rate_limit_exceeded")
#expect(result == "Too many attempts. Please wait a few minutes and try again.")
}
@Test func taskNotFoundCode() {
let result = ErrorMessageParser.parse("error.task_not_found")
#expect(result == "Task not found. It may have been deleted.")
}
@Test func residenceNotFoundCode() {
let result = ErrorMessageParser.parse("error.residence_not_found")
#expect(result == "Property not found. It may have been deleted.")
}
@Test func accessDeniedCode() {
let result = ErrorMessageParser.parse("error.access_denied")
#expect(result == "You don't have permission for this action.")
}
@Test func shareCodeInvalidCode() {
let result = ErrorMessageParser.parse("error.share_code_invalid")
#expect(result == "Invalid share code. Please check and try again.")
}
@Test func propertiesLimitReachedCode() {
let result = ErrorMessageParser.parse("error.properties_limit_reached")
#expect(result == "You've reached your property limit. Upgrade to add more.")
}
@Test func internalErrorCode() {
let result = ErrorMessageParser.parse("error.internal")
#expect(result == "Something went wrong. Please try again.")
}
@Test func titleRequiredCode() {
let result = ErrorMessageParser.parse("error.title_required")
#expect(result == "Title is required.")
}
}
// MARK: - Unknown Error Code Tests
struct UnknownErrorCodeTests {
@Test func unknownErrorCodeGeneratesMessage() {
let result = ErrorMessageParser.parse("error.some_new_error")
#expect(result == "Some new error. Please try again.")
}
@Test func unknownErrorCodeWithSingleWord() {
let result = ErrorMessageParser.parse("error.forbidden")
#expect(result == "Forbidden. Please try again.")
}
}
// MARK: - Network Error Pattern Tests
struct NetworkErrorPatternTests {
@Test func offlineErrorDetected() {
let result = ErrorMessageParser.parse("The Internet connection appears to be offline")
#expect(result == "No internet connection. Please check your network.")
}
@Test func timeoutErrorDetected() {
let result = ErrorMessageParser.parse("The request timed out")
#expect(result == "Request timed out. Please try again.")
}
@Test func connectionLostDetected() {
let result = ErrorMessageParser.parse("The network connection was lost")
#expect(result == "Connection lost. Please try again.")
}
@Test func sslErrorDetected() {
let result = ErrorMessageParser.parse("An SSL error has occurred")
#expect(result == "Secure connection failed. Please try again.")
}
@Test func nsUrlErrorCodeDetected() {
let result = ErrorMessageParser.parse("Error Code=-1009 in domain NSURLErrorDomain")
#expect(result.contains("internet") || result.contains("connect"))
}
@Test func connectionRefusedDetected() {
let result = ErrorMessageParser.parse("Connection refused")
#expect(result == "Unable to connect. The server may be temporarily unavailable.")
}
@Test func socketTimeoutDetected() {
let result = ErrorMessageParser.parse("SocketTimeoutException: connect timed out")
#expect(result == "Request timed out. Please try again.")
}
}
// MARK: - Technical Error Detection Tests
struct TechnicalErrorDetectionTests {
@Test func stackTraceDetected() {
let result = ErrorMessageParser.parse("java.lang.NullPointerException at com.example.App.method(App.kt:42)")
#expect(result == "Something went wrong. Please try again.")
}
@Test func swiftErrorDetected() {
let result = ErrorMessageParser.parse("Fatal error in module.swift:123")
#expect(result == "Something went wrong. Please try again.")
}
@Test func kotlinErrorDetected() {
let result = ErrorMessageParser.parse("Exception at kotlin.coroutines.ContinuationKt.kt:55")
#expect(result == "Something went wrong. Please try again.")
}
@Test func nsErrorDomainDetected() {
let result = ErrorMessageParser.parse("Error Domain=NSURLErrorDomain Code=-1001 UserInfo={NSLocalizedDescription=timed out}")
#expect(result != "Error Domain=NSURLErrorDomain Code=-1001 UserInfo={NSLocalizedDescription=timed out}")
}
}
// MARK: - JSON Error Parsing Tests
struct JSONErrorParsingTests {
@Test func jsonWithErrorFieldParsed() {
let json = #"{"error": "error.invalid_credentials"}"#
let result = ErrorMessageParser.parse(json)
#expect(result == "Invalid username or password. Please try again.")
}
@Test func jsonWithMessageFieldParsed() {
let json = #"{"message": "Something went wrong"}"#
let result = ErrorMessageParser.parse(json)
#expect(result == "Something went wrong")
}
@Test func jsonWithDetailFieldParsed() {
let json = #"{"detail": "Not authorized"}"#
let result = ErrorMessageParser.parse(json)
#expect(result == "Not authorized")
}
@Test func jsonWithDataObjectReturnsGeneric() {
let json = #"{"id": 1, "title": "Test"}"#
let result = ErrorMessageParser.parse(json)
#expect(result == "Request failed. Please check your input and try again.")
}
@Test func invalidJsonReturnsGeneric() {
let json = #"{malformed json"#
let result = ErrorMessageParser.parse(json)
#expect(result == "An error occurred. Please try again.")
}
}
// MARK: - User-Friendly Message Tests
struct UserFriendlyMessageTests {
@Test func shortReadableMessagePassedThrough() {
let result = ErrorMessageParser.parse("Invalid email address")
#expect(result == "Invalid email address")
}
@Test func emptyStringReturnsSelf() {
// Empty/whitespace strings pass through the parser's user-friendly check
let result = ErrorMessageParser.parse("")
#expect(result == "")
}
@Test func whitespaceOnlyReturnsTrimmed() {
let result = ErrorMessageParser.parse(" ")
#expect(result == "")
}
}