apple_kit

Apple-native services for Radroots iOS and macOS apps
git clone https://radroots.dev/git/apple_kit.git
Log | Files | Refs | README

RadrootsKitTestingTests.swift (5078B)


      1 import Foundation
      2 import Testing
      3 import RadrootsKit
      4 import RadrootsKitTesting
      5 
      6 @Test func deterministicLaunchConfigurationAddsStableLocaleArguments() {
      7     let config = RadrootsUITestLaunchConfiguration.deterministic(
      8         environment: ["RADROOTS_TEST": "true"],
      9         arguments: ["--radroots-test"]
     10     )
     11 
     12     #expect(config.environment["RADROOTS_TEST"] == "true")
     13     #expect(config.arguments == [
     14         "--radroots-test",
     15         "-AppleLanguages",
     16         "(en)",
     17         "-AppleLocale",
     18         "en_US_POSIX"
     19     ])
     20 }
     21 
     22 @Test func launchConfigurationMergesEnvironmentOverBaseValues() {
     23     let config = RadrootsUITestLaunchConfiguration(
     24         environment: ["A": "override", "B": "new"],
     25         arguments: []
     26     )
     27 
     28     #expect(config.mergedEnvironment(over: ["A": "old", "C": "keep"]) == [
     29         "A": "override",
     30         "B": "new",
     31         "C": "keep"
     32     ])
     33 }
     34 
     35 @Test func inMemorySecureStoreRoundTripsAndNormalizesKeys() throws {
     36     let store = RadrootsInMemorySecureStore()
     37     let key = RadrootsSecureStoreKey(namespace: " identity ", name: " selected ")
     38 
     39     try store.put(Data("secret".utf8), for: key)
     40 
     41     #expect(try store.contains(RadrootsSecureStoreKey(namespace: "identity", name: "selected")))
     42     #expect(try store.get(key) == Data("secret".utf8))
     43     #expect(store.keys() == [RadrootsSecureStoreKey(namespace: "identity", name: "selected")])
     44 }
     45 
     46 @Test func inMemorySecureStoreRecordsPolicyWithoutReturningSecret() throws {
     47     let store = RadrootsInMemorySecureStore()
     48     let key = RadrootsSecureStoreKey(namespace: "identity", name: "selected")
     49 
     50     try store.put(
     51         Data("secret".utf8),
     52         for: key,
     53         policy: .userPresenceLocalSecret
     54     )
     55 
     56     #expect(try store.policy(for: key) == .userPresenceLocalSecret)
     57     #expect(try store.contains(key))
     58 }
     59 
     60 @Test func inMemorySecureStoreDeletesNamespace() throws {
     61     let store = RadrootsInMemorySecureStore()
     62     let selected = RadrootsSecureStoreKey(namespace: " identity ", name: "selected")
     63     let relay = RadrootsSecureStoreKey(namespace: "relay", name: "selected")
     64 
     65     try store.put(Data("secret".utf8), for: selected)
     66     try store.put(Data("relay".utf8), for: relay)
     67     try store.deleteNamespace(" identity ")
     68 
     69     #expect(try store.get(selected) == nil)
     70     #expect(try store.get(relay) == Data("relay".utf8))
     71 }
     72 
     73 @Test func inMemoryPermissionStatusProviderReturnsDefaultsAndOverrides() async throws {
     74     let provider = RadrootsInMemoryPermissionStatusProvider(
     75         statuses: [.camera: .denied],
     76         defaultStatus: .notDetermined,
     77         observedAt: Date(timeIntervalSince1970: 1)
     78     )
     79 
     80     #expect(try await provider.snapshot(for: .camera).status == .denied)
     81     #expect(try await provider.snapshot(for: .location).status == .notDetermined)
     82 
     83     await provider.setStatus(.authorized, for: .location, observedAt: Date(timeIntervalSince1970: 2))
     84 
     85     let location = try await provider.snapshot(for: .location)
     86     #expect(location.status == .authorized)
     87     #expect(location.observedAt == Date(timeIntervalSince1970: 2))
     88 }
     89 
     90 @Test func fakeLocationServicesTracksRequestsAndResults() async throws {
     91     let reading = try RadrootsLocationReading(
     92         coordinate: RadrootsLocationCoordinate(latitude: 49.2827, longitude: -123.1207),
     93         horizontalAccuracyMeters: 6,
     94         capturedAt: Date(timeIntervalSince1970: 10)
     95     )
     96     let service = RadrootsFakeLocationServices(
     97         availability: RadrootsLocationServicesAvailability(
     98             locationServicesEnabled: true,
     99             authorization: .notDetermined
    100         ),
    101         authorizationAfterRequest: .authorizedWhenInUse,
    102         currentLocationOutcome: .success(reading)
    103     )
    104 
    105     #expect(await service.currentAvailability().authorization == .notDetermined)
    106     #expect(try await service.requestWhenInUseAuthorization() == .authorizedWhenInUse)
    107     #expect(await service.currentAvailability().authorization == .authorizedWhenInUse)
    108 
    109     let result = try await service.currentLocation(try RadrootsCurrentLocationRequest(timeoutSeconds: 2))
    110     #expect(result.reading == reading)
    111     #expect(result.authorization == .authorizedWhenInUse)
    112     #expect(await service.requestAuthorizationCount == 1)
    113     #expect(await service.currentLocationRequestCount == 1)
    114 }
    115 
    116 @Test func fakeLocationServicesCanReturnTypedFailures() async throws {
    117     let reading = try RadrootsLocationReading(
    118         coordinate: RadrootsLocationCoordinate(latitude: 49.2827, longitude: -123.1207),
    119         horizontalAccuracyMeters: 6,
    120         capturedAt: Date(timeIntervalSince1970: 10)
    121     )
    122     let service = RadrootsFakeLocationServices(
    123         availability: RadrootsLocationServicesAvailability(
    124             locationServicesEnabled: true,
    125             authorization: .authorizedWhenInUse
    126         ),
    127         currentLocationOutcome: .success(reading)
    128     )
    129     await service.setCurrentLocationOutcome(.failure(.timeout("timed out")))
    130 
    131     await #expect(throws: RadrootsLocationServicesError.timeout("timed out")) {
    132         _ = try await service.currentLocation(try RadrootsCurrentLocationRequest(timeoutSeconds: 2))
    133     }
    134 }