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 }