RadrootsAppleMediaPickerTests.swift (3393B)
1 import Foundation 2 import Testing 3 4 @testable import RadrootsKit 5 6 @Test func captureAsyncSupportRunsCleanupOnTimeout() async throws { 7 let probe = RadrootsCaptureCleanupProbe() 8 9 await #expect(throws: RadrootsCaptureIntakeError.transientFailure) { 10 let _: Int = try await RadrootsAppleCaptureAsyncSupport.awaitMainActorCallback( 11 timeout: 0.001, 12 timeoutMessage: "timeout" 13 ) { _, setCleanup in 14 setCleanup { 15 probe.recordCleanup() 16 } 17 } 18 } 19 20 try await Task.sleep(nanoseconds: 20_000_000) 21 #expect(await probe.cleanupCount == 1) 22 } 23 24 @Test func captureAsyncSupportRunsCleanupOnceOnDoubleCompletion() async throws { 25 let probe = RadrootsCaptureCleanupProbe() 26 27 let value: Int = try await RadrootsAppleCaptureAsyncSupport.awaitMainActorCallback( 28 timeout: 10, 29 timeoutMessage: "timeout" 30 ) { completion, setCleanup in 31 setCleanup { 32 probe.recordCleanup() 33 } 34 completion(.success(7)) 35 completion(.success(8)) 36 } 37 38 try await Task.sleep(nanoseconds: 20_000_000) 39 #expect(value == 7) 40 #expect(await probe.cleanupCount == 1) 41 } 42 43 @Test func captureAsyncSupportRunsCleanupOnTaskCancellation() async throws { 44 let probe = RadrootsCaptureCleanupProbe() 45 let task = Task<Int, any Error> { 46 try await RadrootsAppleCaptureAsyncSupport.awaitMainActorCallback( 47 timeout: 10, 48 timeoutMessage: "timeout" 49 ) { _, setCleanup in 50 setCleanup { 51 probe.recordCleanup() 52 } 53 } 54 } 55 56 task.cancel() 57 58 await #expect(throws: RadrootsCaptureIntakeError.userCancelled) { 59 _ = try await task.value 60 } 61 try await Task.sleep(nanoseconds: 20_000_000) 62 #expect(await probe.cleanupCount == 1) 63 } 64 65 #if !canImport(UIKit) 66 @Test func appleMediaPickerReportsUnavailableWithoutUIKit() async throws { 67 let picker = try RadrootsAppleMediaPicker(fileAccess: mediaPickerTestFileAccess()) 68 let support = try await picker.currentSupport() 69 70 #expect(!support.importAvailable) 71 #expect(!support.cameraCaptureAvailable) 72 #expect(support.supportedImportKinds.isEmpty) 73 #expect(support.supportedCaptureKinds.isEmpty) 74 75 await #expect(throws: RadrootsCaptureIntakeError.unavailable) { 76 _ = try await picker.importMedia(RadrootsMediaImportRequest()) 77 } 78 await #expect(throws: RadrootsCaptureIntakeError.unavailable) { 79 _ = try await picker.captureMedia(RadrootsMediaCaptureRequest()) 80 } 81 } 82 #endif 83 84 private func mediaPickerTestFileAccess() throws -> RadrootsAppleFileAccess { 85 let root = FileManager.default.temporaryDirectory 86 .appendingPathComponent("radroots-media-picker-\(UUID().uuidString)", isDirectory: true) 87 let roots = try RadrootsAppleFileRoots( 88 appIdentifier: "org.radroots.media-picker-test", 89 dataRoot: root.appendingPathComponent("data", isDirectory: true), 90 cacheRoot: root.appendingPathComponent("cache", isDirectory: true), 91 temporaryRoot: root.appendingPathComponent("temporary", isDirectory: true) 92 ) 93 return RadrootsAppleFileAccess(roots: roots) 94 } 95 96 @MainActor 97 private final class RadrootsCaptureCleanupProbe { 98 private(set) var cleanupCount = 0 99 100 func recordCleanup() { 101 cleanupCount += 1 102 } 103 }