apple_kit

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

RadrootsAppleExternalActionsTests.swift (3931B)


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