TeraRevisionPreparationTests.swift (4671B)
1 import Foundation 2 @testable import TeraApp 3 import XCTest 4 5 extension TeraAddStoreTests { 6 @MainActor 7 func testStaleRevisionCaptureCannotEnterRuntimeAndRetryRetainsOriginalForm() async throws { 8 let backend = AddBackend() 9 let client = try await Self.startedClient(backend) 10 let preparation = TeraRevisionPreparation(client: client, media: nil) 11 let target = TeraRevisionTarget(cardID: String(repeating: "a", count: 64), 12 sourceEventID: String(repeating: "b", count: 64), sourceAddress: nil, 13 authorPublicKey: String(repeating: "ab", count: 32)) 14 var form = TeraAddStore(runtimeClient: client).form 15 form.content = "Captured before suspension" 16 do { 17 _ = try await preparation.prepare(target: target, form: form, 18 identifier: { String(repeating: "c", count: 32) }, 19 ensureCurrent: { throw CancellationError() }) 20 XCTFail("Stale native generation must fail before admission") 21 } catch is CancellationError {} 22 let before = await backend.revisionPlanCount() 23 XCTAssertEqual(before, 0) 24 form.content = "Unrelated newer editing" 25 let recovered = try await preparation.prepare(target: target, form: form, 26 identifier: { XCTFail("Must retain the original identity"); return "" }, 27 ensureCurrent: {}) 28 XCTAssertEqual(recovered.replacement.form?.content, "Captured before suspension") 29 XCTAssertEqual(recovered.operationID, String(repeating: "c", count: 32)) 30 _ = try await client.stop() 31 } 32 33 @MainActor 34 func testRevisionLostReceiptRetainsCapturedRequestAndOneGraph() async throws { 35 let backend = AddBackend() 36 let client = try await Self.startedClient(backend) 37 let store = TeraAddStore(runtimeClient: client) 38 await store.configure(snapshot: backend.snapshot()) 39 await store.start() 40 var original = store.form 41 original.content = "Original form" 42 let legacy = try await backend.saveAddIntent(input: TeraAddRuntimeInput(form: original, media: []), 43 existingDraftID: nil, expectedRevision: nil) 44 await store.retractAndRevise(Self.card(localOperationID: legacy.id)) 45 store.updateForm(\.content, "Captured correction") 46 await backend.failNextRevisionReceipt() 47 await store.save() 48 XCTAssertNil(store.activeDraft) 49 XCTAssertTrue(store.revisionPreparation.isCaptured) 50 XCTAssertFalse(store.isFormEditable) 51 XCTAssertTrue(store.canSave) 52 store.updateForm(\.content, "Must not replace the uncertain capture") 53 XCTAssertEqual(store.form.content, "Captured correction") 54 await store.save() 55 let prepared = try XCTUnwrap(store.activeDraft) 56 XCTAssertTrue(prepared.isRevision) 57 XCTAssertEqual(prepared.form?.content, "Captured correction") 58 XCTAssertFalse(store.revisionPreparation.isCaptured) 59 await store.submit() 60 XCTAssertEqual(store.activeDraft?.id, prepared.id) 61 let count = await backend.revisionPlanCount() 62 XCTAssertEqual(count, 1) 63 _ = try await client.stop() 64 } 65 66 @MainActor 67 func testRevisionOriginalFormUsesExactSourceKeyAndRejectsUnavailableOrWrongAuthor() async throws { 68 let backend = AddBackend() 69 let client = try await Self.startedClient(backend) 70 let store = TeraAddStore(runtimeClient: client) 71 await store.configure(snapshot: backend.snapshot()) 72 await store.start() 73 var form = store.form 74 form.content = "Retained source form" 75 let source = try await backend.saveAddIntent(input: TeraAddRuntimeInput(form: form, media: []), 76 existingDraftID: nil, expectedRevision: nil) 77 var card = Self.card(localOperationID: String(repeating: "f", count: 32)) 78 card.localSourceDraftID = source.id 79 let editing = try await TeraAddCardIntents.revision(card, author: card.authorPublicKey, client: client) 80 XCTAssertEqual(editing.form, form) 81 for author in [nil, Optional(String(repeating: "c", count: 64))] { 82 do { 83 _ = try await TeraAddCardIntents.revision(card, author: author, client: client) 84 XCTFail("Foreign or absent author must fail") 85 } catch {} 86 } 87 card.localSourceDraftID = String(repeating: "d", count: 32) 88 do { 89 _ = try await TeraAddCardIntents.revision(card, author: card.authorPublicKey, client: client) 90 XCTFail("Unavailable original must not start a revision") 91 } catch {} 92 let count = await backend.revisionPlanCount() 93 XCTAssertEqual(count, 0) 94 _ = try await client.stop() 95 } 96 }