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 }