Add 87 new tests (384 total) covering ValidationRules/ValidationError, PasswordResetViewModel navigation and client-side validation, WidgetAction Codable/Equatable/accessors, parseDate, and ThemeID enum properties. Updates greenfield CSV for AUTH-012/017/018, NOTIF-006/007, WID-003, THEME-002. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
267 lines
8.5 KiB
Swift
267 lines
8.5 KiB
Swift
//
|
|
// ValidationRulesTests.swift
|
|
// CaseraTests
|
|
//
|
|
// Unit tests for ValidationError and ValidationRules (distinct from ValidationHelpers).
|
|
//
|
|
|
|
import Testing
|
|
@testable import Casera
|
|
|
|
// MARK: - ValidationError errorDescription Tests
|
|
|
|
struct ValidationErrorTests {
|
|
|
|
@Test func requiredFieldErrorDescription() {
|
|
let error = ValidationError.required(field: "Email")
|
|
#expect(error.errorDescription == "Email is required")
|
|
}
|
|
|
|
@Test func invalidEmailErrorDescription() {
|
|
let error = ValidationError.invalidEmail
|
|
#expect(error.errorDescription == "Please enter a valid email address")
|
|
}
|
|
|
|
@Test func passwordTooShortErrorDescription() {
|
|
let error = ValidationError.passwordTooShort(minLength: 8)
|
|
#expect(error.errorDescription == "Password must be at least 8 characters")
|
|
}
|
|
|
|
@Test func passwordMismatchErrorDescription() {
|
|
let error = ValidationError.passwordMismatch
|
|
#expect(error.errorDescription == "Passwords do not match")
|
|
}
|
|
|
|
@Test func passwordMissingLetterErrorDescription() {
|
|
let error = ValidationError.passwordMissingLetter
|
|
#expect(error.errorDescription == "Password must contain at least one letter")
|
|
}
|
|
|
|
@Test func passwordMissingNumberErrorDescription() {
|
|
let error = ValidationError.passwordMissingNumber
|
|
#expect(error.errorDescription == "Password must contain at least one number")
|
|
}
|
|
|
|
@Test func invalidCodeErrorDescription() {
|
|
let error = ValidationError.invalidCode(expectedLength: 6)
|
|
#expect(error.errorDescription == "Code must be 6 digits")
|
|
}
|
|
|
|
@Test func invalidUsernameErrorDescription() {
|
|
let error = ValidationError.invalidUsername
|
|
#expect(error.errorDescription == "Username can only contain letters, numbers, and underscores")
|
|
}
|
|
|
|
@Test func customMessageErrorDescription() {
|
|
let error = ValidationError.custom(message: "Something went wrong")
|
|
#expect(error.errorDescription == "Something went wrong")
|
|
}
|
|
}
|
|
|
|
// MARK: - Email Validation Tests
|
|
|
|
struct ValidationRulesEmailTests {
|
|
|
|
@Test func emptyEmailReturnsRequired() {
|
|
let error = ValidationRules.validateEmail("")
|
|
#expect(error?.errorDescription == "Email is required")
|
|
}
|
|
|
|
@Test func whitespaceOnlyEmailReturnsRequired() {
|
|
let error = ValidationRules.validateEmail(" ")
|
|
#expect(error?.errorDescription == "Email is required")
|
|
}
|
|
|
|
@Test func invalidEmailReturnsInvalidEmail() {
|
|
let error = ValidationRules.validateEmail("notanemail")
|
|
#expect(error?.errorDescription == "Please enter a valid email address")
|
|
}
|
|
|
|
@Test func validEmailReturnsNil() {
|
|
let error = ValidationRules.validateEmail("user@example.com")
|
|
#expect(error == nil)
|
|
}
|
|
|
|
@Test func isValidEmailReturnsTrueForValid() {
|
|
#expect(ValidationRules.isValidEmail("user@example.com"))
|
|
}
|
|
|
|
@Test func isValidEmailReturnsFalseForInvalid() {
|
|
#expect(!ValidationRules.isValidEmail("notanemail"))
|
|
}
|
|
}
|
|
|
|
// MARK: - Password Validation Tests
|
|
|
|
struct ValidationRulesPasswordTests {
|
|
|
|
@Test func emptyPasswordReturnsRequired() {
|
|
let error = ValidationRules.validatePassword("")
|
|
#expect(error?.errorDescription == "Password is required")
|
|
}
|
|
|
|
@Test func shortPasswordReturnsTooShort() {
|
|
let error = ValidationRules.validatePassword("abc")
|
|
#expect(error?.errorDescription == "Password must be at least 8 characters")
|
|
}
|
|
|
|
@Test func validPasswordReturnsNil() {
|
|
let error = ValidationRules.validatePassword("longpassword")
|
|
#expect(error == nil)
|
|
}
|
|
|
|
@Test func exactMinLengthPasswordReturnsNil() {
|
|
let error = ValidationRules.validatePassword("12345678")
|
|
#expect(error == nil)
|
|
}
|
|
}
|
|
|
|
// MARK: - Password Strength Tests
|
|
|
|
struct ValidationRulesPasswordStrengthTests {
|
|
|
|
@Test func emptyPasswordReturnsRequired() {
|
|
let error = ValidationRules.validatePasswordStrength("")
|
|
#expect(error?.errorDescription == "Password is required")
|
|
}
|
|
|
|
@Test func noLetterReturnsMissingLetter() {
|
|
let error = ValidationRules.validatePasswordStrength("123456")
|
|
#expect(error?.errorDescription == "Password must contain at least one letter")
|
|
}
|
|
|
|
@Test func noNumberReturnsMissingNumber() {
|
|
let error = ValidationRules.validatePasswordStrength("abcdef")
|
|
#expect(error?.errorDescription == "Password must contain at least one number")
|
|
}
|
|
|
|
@Test func letterAndNumberReturnsNil() {
|
|
let error = ValidationRules.validatePasswordStrength("abc123")
|
|
#expect(error == nil)
|
|
}
|
|
|
|
@Test func isValidPasswordReturnsTrueForStrong() {
|
|
#expect(ValidationRules.isValidPassword("abc123"))
|
|
}
|
|
|
|
@Test func isValidPasswordReturnsFalseForLettersOnly() {
|
|
#expect(!ValidationRules.isValidPassword("abcdef"))
|
|
}
|
|
|
|
@Test func isValidPasswordReturnsFalseForNumbersOnly() {
|
|
#expect(!ValidationRules.isValidPassword("123456"))
|
|
}
|
|
}
|
|
|
|
// MARK: - Password Match Tests
|
|
|
|
struct ValidationRulesPasswordMatchTests {
|
|
|
|
@Test func matchingPasswordsReturnsNil() {
|
|
let error = ValidationRules.validatePasswordMatch("abc123", "abc123")
|
|
#expect(error == nil)
|
|
}
|
|
|
|
@Test func mismatchedPasswordsReturnsMismatch() {
|
|
let error = ValidationRules.validatePasswordMatch("abc123", "xyz789")
|
|
#expect(error?.errorDescription == "Passwords do not match")
|
|
}
|
|
|
|
@Test func caseSensitiveMismatch() {
|
|
let error = ValidationRules.validatePasswordMatch("Password", "password")
|
|
#expect(error?.errorDescription == "Passwords do not match")
|
|
}
|
|
}
|
|
|
|
// MARK: - Code Validation Tests
|
|
|
|
struct ValidationRulesCodeTests {
|
|
|
|
@Test func emptyCodeReturnsRequired() {
|
|
let error = ValidationRules.validateCode("")
|
|
#expect(error?.errorDescription == "Code is required")
|
|
}
|
|
|
|
@Test func wrongLengthReturnsInvalidCode() {
|
|
let error = ValidationRules.validateCode("123")
|
|
#expect(error?.errorDescription == "Code must be 6 digits")
|
|
}
|
|
|
|
@Test func nonNumericCodeReturnsInvalidCode() {
|
|
let error = ValidationRules.validateCode("abcdef")
|
|
#expect(error?.errorDescription == "Code must be 6 digits")
|
|
}
|
|
|
|
@Test func validSixDigitCodeReturnsNil() {
|
|
let error = ValidationRules.validateCode("123456")
|
|
#expect(error == nil)
|
|
}
|
|
|
|
@Test func customLengthFourDigitCode() {
|
|
let error = ValidationRules.validateCode("1234", expectedLength: 4)
|
|
#expect(error == nil)
|
|
}
|
|
|
|
@Test func customLengthWrongDigitCount() {
|
|
let error = ValidationRules.validateCode("123", expectedLength: 4)
|
|
#expect(error?.errorDescription == "Code must be 4 digits")
|
|
}
|
|
}
|
|
|
|
// MARK: - Username Validation Tests
|
|
|
|
struct ValidationRulesUsernameTests {
|
|
|
|
@Test func emptyUsernameReturnsRequired() {
|
|
let error = ValidationRules.validateUsername("")
|
|
#expect(error?.errorDescription == "Username is required")
|
|
}
|
|
|
|
@Test func validAlphanumericUsernameReturnsNil() {
|
|
let error = ValidationRules.validateUsername("john_doe123")
|
|
#expect(error == nil)
|
|
}
|
|
|
|
@Test func usernameWithSpacesReturnsInvalid() {
|
|
let error = ValidationRules.validateUsername("john doe")
|
|
#expect(error?.errorDescription == "Username can only contain letters, numbers, and underscores")
|
|
}
|
|
|
|
@Test func usernameWithSpecialCharsReturnsInvalid() {
|
|
let error = ValidationRules.validateUsername("user@name!")
|
|
#expect(error?.errorDescription == "Username can only contain letters, numbers, and underscores")
|
|
}
|
|
}
|
|
|
|
// MARK: - Required Field Validation Tests
|
|
|
|
struct ValidationRulesRequiredTests {
|
|
|
|
@Test func emptyValueReturnsRequired() {
|
|
let error = ValidationRules.validateRequired("", fieldName: "Name")
|
|
#expect(error?.errorDescription == "Name is required")
|
|
}
|
|
|
|
@Test func whitespaceOnlyReturnsRequired() {
|
|
let error = ValidationRules.validateRequired(" ", fieldName: "Name")
|
|
#expect(error?.errorDescription == "Name is required")
|
|
}
|
|
|
|
@Test func nonEmptyReturnsNil() {
|
|
let error = ValidationRules.validateRequired("hello", fieldName: "Name")
|
|
#expect(error == nil)
|
|
}
|
|
|
|
@Test func isNotEmptyReturnsTrueForNonEmpty() {
|
|
#expect(ValidationRules.isNotEmpty("hello"))
|
|
}
|
|
|
|
@Test func isNotEmptyReturnsFalseForEmpty() {
|
|
#expect(!ValidationRules.isNotEmpty(""))
|
|
}
|
|
|
|
@Test func isNotEmptyReturnsFalseForWhitespace() {
|
|
#expect(!ValidationRules.isNotEmpty(" "))
|
|
}
|
|
}
|