apple_kit

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

RadrootsAppleExternalActionsTests.swift (3833B)


      1 import Foundation
      2 import Testing
      3 
      4 @testable import RadrootsKit
      5 
      6 @Test func appleExternalActionsOpensAppSettingsThroughAdapter() async throws {
      7     let settingsURL = try #require(URL(string: "app-settings:radroots"))
      8     let probe = RadrootsExternalActionAdapterProbe(appSettingsURL: settingsURL)
      9     let service = RadrootsAppleExternalActions(adapters: probe.adapters())
     10 
     11     let capability = await service.canOpen(.appSettings)
     12     try await service.open(RadrootsExternalActionRequest(destination: .appSettings))
     13 
     14     #expect(capability.destination == .appSettings)
     15     #expect(capability.canOpen)
     16     #expect(await probe.canOpenURLs == [settingsURL])
     17     #expect(await probe.openedURLs == [settingsURL])
     18 }
     19 
     20 @Test func appleExternalActionsReportsUnavailableAppSettingsWithoutAPlatformUrl() async {
     21     let probe = RadrootsExternalActionAdapterProbe(appSettingsURL: nil)
     22     let service = RadrootsAppleExternalActions(adapters: probe.adapters())
     23 
     24     let capability = await service.canOpen(.appSettings)
     25 
     26     #expect(!capability.canOpen)
     27     await #expect(throws: RadrootsExternalActionError.unavailable) {
     28         try await service.open(RadrootsExternalActionRequest(destination: .appSettings))
     29     }
     30     #expect(await probe.canOpenURLs.isEmpty)
     31     #expect(await probe.openedURLs.isEmpty)
     32 }
     33 
     34 @Test func appleExternalActionsMapsPlatformOpenFailure() async throws {
     35     let destination = try RadrootsExternalActionDestination.web("https://radroots.org")
     36     let url = try #require(destination.url)
     37     let probe = RadrootsExternalActionAdapterProbe(openResult: false)
     38     let service = RadrootsAppleExternalActions(adapters: probe.adapters())
     39 
     40     await #expect(throws: RadrootsExternalActionError.transientFailure) {
     41         try await service.open(RadrootsExternalActionRequest(destination: destination))
     42     }
     43 
     44     #expect(await probe.openedURLs == [url])
     45 }
     46 
     47 @Test func appleExternalActionsChecksExternalDestinationCapabilities() async throws {
     48     let destination = try RadrootsExternalActionDestination.nostr("nostr:npub1qqqqqq")
     49     let url = try #require(destination.url)
     50     let probe = RadrootsExternalActionAdapterProbe(canOpenResult: false)
     51     let service = RadrootsAppleExternalActions(adapters: probe.adapters())
     52 
     53     let capability = await service.canOpen(destination)
     54 
     55     #expect(capability.destination == destination)
     56     #expect(!capability.canOpen)
     57     #expect(await probe.canOpenURLs == [url])
     58 }
     59 
     60 private actor RadrootsExternalActionAdapterProbe {
     61     private let appSettingsURLValue: URL?
     62     private let canOpenResult: Bool
     63     private let openResult: Bool
     64     private var canOpenURLsValue: [URL]
     65     private var openedURLsValue: [URL]
     66 
     67     init(
     68         appSettingsURL: URL? = URL(string: "app-settings:radroots"),
     69         canOpenResult: Bool = true,
     70         openResult: Bool = true
     71     ) {
     72         appSettingsURLValue = appSettingsURL
     73         self.canOpenResult = canOpenResult
     74         self.openResult = openResult
     75         canOpenURLsValue = []
     76         openedURLsValue = []
     77     }
     78 
     79     nonisolated func adapters() -> RadrootsAppleExternalActionsAdapters {
     80         RadrootsAppleExternalActionsAdapters(
     81             appSettingsURL: {
     82                 await self.appSettingsURL()
     83             },
     84             canOpenURL: { url in
     85                 await self.canOpen(url)
     86             },
     87             openURL: { url in
     88                 await self.open(url)
     89             }
     90         )
     91     }
     92 
     93     private func appSettingsURL() -> URL? {
     94         appSettingsURLValue
     95     }
     96 
     97     private func canOpen(_ url: URL) -> Bool {
     98         canOpenURLsValue.append(url)
     99         return canOpenResult
    100     }
    101 
    102     private func open(_ url: URL) -> Bool {
    103         openedURLsValue.append(url)
    104         return openResult
    105     }
    106 
    107     var canOpenURLs: [URL] {
    108         canOpenURLsValue
    109     }
    110 
    111     var openedURLs: [URL] {
    112         openedURLsValue
    113     }
    114 }