TeraComposerStartupTests.swift (3417B)
1 import Foundation 2 @testable import TeraApp 3 import XCTest 4 5 @MainActor 6 final class TeraComposerStartupTests: XCTestCase { 7 func testSlowFailingMediaAndLegacyStartupLeaveEditingAndRecoveryAvailable() async throws { 8 let backend = try TeraScopeBackend() 9 let client = try await TeraScopeFixtures.client(backend) 10 let media = RecoveryMediaFailure() 11 let legacy = await backend.pause(.drafts, fails: true) 12 let store = TeraAddStore(runtimeClient: client, media: media) 13 store.configure(snapshot: TeraScopeFixtures.snapshot()) 14 let startup = Task { await store.start() } 15 await media.supportPause.entered.wait() 16 await legacy.entered.wait() 17 XCTAssertEqual(store.state, .ready) 18 XCTAssertTrue(store.canSave) 19 await TeraScopeFixtures.eventually { !store.recovery.isLoading } 20 XCTAssertNil(store.recovery.composerError) 21 store.updateForm(\.content, "editing during media recovery") 22 await store.save() 23 XCTAssertEqual(store.composerState, .saved) 24 await media.supportPause.resume.open() 25 await legacy.resume.open() 26 await startup.value 27 XCTAssertEqual(store.state, .ready) 28 XCTAssertEqual(store.form.content, "editing during media recovery") 29 store.stop() 30 _ = try await client.stop() 31 } 32 33 func testReconciliationFailureIsReportedSeparatelyFromReadyComposer() async throws { 34 let backend = try TeraScopeBackend() 35 let client = try await TeraScopeFixtures.client(backend) 36 let media = RecoveryMediaFailure() 37 await media.supportPause.resume.open() 38 let store = TeraAddStore(runtimeClient: client, media: media) 39 store.configure(snapshot: TeraScopeFixtures.snapshot()) 40 await store.start() 41 XCTAssertEqual(store.state, .ready) 42 XCTAssertTrue(store.canSave) 43 XCTAssertEqual(store.recovery.transfers.message, "Photo recovery needs attention. Saved editing is still available.") 44 XCTAssertNil(store.message) 45 store.stop() 46 _ = try await client.stop() 47 } 48 49 func testCancelledSchemaLoadCannotEnableEditorThroughLateReply() async throws { 50 let backend = try TeraScopeBackend() 51 let client = try await TeraScopeFixtures.client(backend) 52 let schema = await backend.pause(.schemas) 53 let stores = TeraProductStores(runtimeClient: client) 54 stores.configure(snapshot: TeraScopeFixtures.snapshot()) 55 let startup = Task { await stores.resume() } 56 await schema.entered.wait() 57 XCTAssertFalse(stores.add.isProductReady) 58 XCTAssertTrue(stores.add.schemas.isEmpty) 59 stores.stop() 60 await startup.value 61 await schema.resume.open() 62 _ = try await client.stop() 63 XCTAssertFalse(stores.add.isProductReady) 64 XCTAssertTrue(stores.add.schemas.isEmpty) 65 XCTAssertEqual(stores.add.observationState, .stopped) 66 } 67 } 68 69 private actor RecoveryMediaFailure: TeraAddMediaHandling { 70 let supportPause = ResourceTestPause() 71 func support() async throws -> TeraAddMediaSupport { 72 await supportPause.wait() 73 throw TeraScopeFixtures.failure() 74 } 75 76 func recoverNativeUploads(client _: TeraRuntimeClient) throws -> TeraNativeRecoveryProgress { 77 throw TeraScopeFixtures.failure() 78 } 79 80 func importImages(limit _: Int) throws -> [TeraPreparedMedia] { 81 throw TeraScopeFixtures.failure() 82 } 83 84 func captureImage() throws -> TeraPreparedMedia { 85 throw TeraScopeFixtures.failure() 86 } 87 88 func open(_: [TeraPreparedMedia]) throws -> TeraOpenedMedia { 89 throw TeraScopeFixtures.failure() 90 } 91 }