- 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>
222 lines
7.6 KiB
Swift
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 == "")
|
|
}
|
|
}
|