TeraUserMessagesTests.swift (5431B)
1 import Foundation 2 import RadrootsKit 3 @testable import TeraApp 4 import XCTest 5 6 final class TeraUserMessagesTests: XCTestCase { 7 func testMessageKeyInventoryIsClosedAndLocalized() { 8 XCTAssertEqual( 9 Set(TeraUserMessageKey.allCases.map(\.rawValue)), 10 [ 11 "error.add.media_unavailable", 12 "error.add.operation_failed", 13 "error.background_transfer.failed", 14 "error.background_transfer.unavailable", 15 "error.configuration.invalid", 16 "error.diagnostics.export_failed", 17 "error.diagnostics.prepare_failed", 18 "error.file.operation_failed", 19 "error.identity.operation_failed", 20 "error.location.unavailable", 21 "error.network.unavailable", 22 "error.network.policy", 23 "error.result.partial", 24 "error.operation.conflict", 25 "error.operation.outcome_unknown", 26 "error.protected_data.unavailable", 27 "error.state.changed", 28 "error.storage.full", 29 "error.storage.receipt_capacity", 30 "error.version.unsupported", 31 "error.operation.cancelled", 32 "error.operation.try_again", 33 "error.permission.denied", 34 "error.profile.unavailable", 35 "error.request.invalid", 36 "error.runtime.observation_unavailable", 37 "error.runtime.operation_failed", 38 "error.runtime.unavailable", 39 "error.search.unavailable", 40 "error.secure_state.unavailable", 41 "error.settings.operation_failed", 42 "error.shutdown.failed", 43 "error.startup.failed", 44 "error.today.changed", 45 "error.today.select_network", 46 "error.today.unavailable", 47 "error.user_presence.unavailable", 48 "status.diagnostics.export_succeeded", 49 ] 50 ) 51 for key in TeraUserMessageKey.allCases { 52 XCTAssertFalse(TeraUserMessages.text(key).isEmpty, key.rawValue) 53 } 54 } 55 56 func testAppleErrorsMapToClosedUserMessageKeys() { 57 let vectors: [(Error, TeraUserMessageKey)] = [ 58 (RadrootsCaptureIntakeError.invalidRequest, .invalidRequest), 59 (RadrootsCaptureIntakeError.unavailable, .addMediaUnavailable), 60 (RadrootsCaptureIntakeError.permissionDenied, .permissionDenied), 61 (RadrootsCaptureIntakeError.userCancelled, .operationCancelled), 62 (RadrootsCaptureIntakeError.transientFailure, .tryAgain), 63 (RadrootsCaptureIntakeError.permanentFailure, .addMediaUnavailable), 64 (RadrootsBackgroundTransferError.invalidRequest, .invalidRequest), 65 (RadrootsBackgroundTransferError.unavailable, .backgroundTransferUnavailable), 66 (RadrootsBackgroundTransferError.transferFailure, .backgroundTransferFailed), 67 (RadrootsBackgroundTransferError.persistenceFailure, .secureStateUnavailable), 68 (RadrootsDocumentInterchangeError.notFound, .fileOperationFailed), 69 (RadrootsDocumentInterchangeError.userCancelled, .operationCancelled), 70 (RadrootsDocumentInterchangeError.permissionDenied, .permissionDenied), 71 (RadrootsAppLocalStateResetError.keychainFailure, .secureStateUnavailable), 72 (RadrootsAppleMediaPreparationError.preparationFailure, .addMediaUnavailable), 73 (RadrootsTelemetryError.invalidRequest, .invalidRequest), 74 (RadrootsExternalActionError.blockedByPolicy, .permissionDenied), 75 (RadrootsExternalActionError.transientFailure, .tryAgain), 76 (RadrootsAppleFileError.notFound, .fileOperationFailed), 77 (RadrootsAppleFileError.permissionDenied, .permissionDenied), 78 (RadrootsLocationServicesError.permissionDenied, .permissionDenied), 79 (RadrootsLocationServicesError.timeout, .locationUnavailable), 80 (RadrootsUserPresenceError.userCancelled, .operationCancelled), 81 (RadrootsUserPresenceError.unavailable, .userPresenceUnavailable), 82 (RadrootsBackgroundTaskError.schedulerFailure, .runtimeUnavailable), 83 (RadrootsAppleSecurityError.userCancelled, .operationCancelled), 84 (RadrootsAppleSecurityError.keychainFailure, .secureStateUnavailable), 85 (RadrootsAppleMobileStoreError.invalidPublicKey, .invalidRequest), 86 (RadrootsAppleMobileStoreError.fileSystemFailure, .secureStateUnavailable), 87 (RadrootsVerifiedArtifactAccessError.invalidDescriptor, .invalidRequest), 88 (RadrootsVerifiedArtifactAccessError.artifactCorrupt, .fileOperationFailed), 89 (RadrootsIdentityCustodyError.cryptographyFailed, .secureStateUnavailable), 90 ] 91 92 for (error, expected) in vectors { 93 XCTAssertEqual( 94 TeraUserMessages.key(for: error, fallback: .runtimeOperationFailed), 95 expected 96 ) 97 } 98 } 99 100 func testDependencyDiagnosticsAndRuntimeSafeMessagesCannotReachUserText() { 101 let canaries = [ 102 "nsec1step264canary", 103 "/Users/private/step264.sqlite", 104 "wss://private.invalid/relay", 105 ] 106 let errors: [Error] = [ 107 NSError( 108 domain: canaries[1], 109 code: 1, 110 userInfo: [NSLocalizedDescriptionKey: canaries.joined(separator: " ")] 111 ), 112 TeraRuntimeFailure.local( 113 operation: canaries[2], 114 code: "private.failure", 115 safeMessage: canaries[0] 116 ), 117 TeraConfigurationError.missing(canaries[1]), 118 TeraIdentityStoreError.custody(canaries[0]), 119 ] 120 121 for error in errors { 122 let rendered = TeraUserMessages.text(for: error, fallback: .runtimeOperationFailed) 123 XCTAssertFalse(rendered.isEmpty) 124 for canary in canaries { 125 XCTAssertFalse(rendered.contains(canary)) 126 } 127 } 128 } 129 }