field_ios

In-the-field app for Radroots on iOS
git clone https://radroots.dev/git/field_ios.git
Log | Files | Refs | README | LICENSE

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 }