TeraUploadRenewalFFITests.swift (4141B)
1 import Foundation 2 @testable import TeraApp 3 import TeraKitBindings 4 import XCTest 5 6 final class TeraUploadRenewalFFITests: XCTestCase { 7 func testGeneratedRenewalKeepsDeniedReservationsAndEnforcesBudgetAfterReconstruction() async throws { 8 let fixture = try MediaOwnershipFixture() 9 defer { fixture.remove() } 10 let runtime = try await fixture.runtime() 11 try await runtime.configureSimulatorRelays(loopbackRelays: ["ws://127.0.0.1:19999"]) 12 let backend = TeraGeneratedRuntimeBackend(runtime: runtime) 13 let request = try await submission(backend: backend, media: fixture.media) 14 let file = try fixture.original() 15 defer { try? file.close() } 16 let handle = try TeraPreparedMediaHandle(media: fixture.media, fileDescriptor: UInt64(file.fileDescriptor)) 17 let initial = try await backend.prepareSubmission(request: request, media: [handle]) 18 do { _ = try await backend.prepareSubmissionUpload(input: .init(request: request, expectedRevision: initial.revision, media: handle)) 19 XCTFail("No signer is installed") 20 } catch {} 21 var retained = try await backend.submissionStatus(request: request) 22 XCTAssertEqual(retained.media[0].authorizations.count, 1) 23 for expectedCount in 2 ... 3 { 24 // The real runtime clock drives expiry/backoff; the denied native attempt 25 // is explicitly reconciled failed for this generated-boundary test. 26 try await Task.sleep(for: .milliseconds(1100)) 27 let prior = try XCTUnwrap(retained.media[0].authorizations.last) 28 let renewal = try TeraSubmissionUploadRenewal(priorRevision: XCTUnwrap(prior.revision), priorAttempt: prior.operationID, nativeFailed: true) 29 do { _ = try await backend.renewSubmissionUpload(input: .init(request: request, expectedRevision: retained.revision, media: handle), renewal: renewal) 30 XCTFail("Renewal must not manufacture a signer") 31 } catch {} 32 retained = try await backend.submissionStatus(request: request) 33 XCTAssertEqual(retained.media[0].authorizations.count, expectedCount) 34 XCTAssertEqual(retained.captured, initial.captured) 35 XCTAssertEqual(retained.operationID, initial.operationID) 36 XCTAssertEqual(retained.intentID, initial.intentID) 37 } 38 _ = try await runtime.shutdown() 39 let reopened = try await fixture.runtime() 40 try await reopened.configureSimulatorRelays(loopbackRelays: ["ws://127.0.0.1:19999"]) 41 let consumer = TeraGeneratedRuntimeBackend(runtime: reopened) 42 let restored = try await consumer.submissionStatus(request: request) 43 XCTAssertEqual(restored, retained) 44 let last = try XCTUnwrap(restored.media[0].authorizations.last) 45 do { 46 _ = try await consumer.renewSubmissionUpload(input: .init(request: request, expectedRevision: restored.revision, media: handle), 47 renewal: .init(priorRevision: XCTUnwrap(last.revision), priorAttempt: last.operationID, nativeFailed: true)) 48 XCTFail("Reopening cannot reset the authorization budget") 49 } catch let failure as TeraRuntimeFailure { XCTAssertEqual(failure.code, "submission_upload_attempts_exhausted") } 50 let final = try await consumer.submissionStatus(request: request) 51 XCTAssertEqual(final, restored) 52 _ = try await reopened.shutdown() 53 } 54 55 private func submission(backend: TeraGeneratedRuntimeBackend, media: TeraPreparedMedia) async throws -> TeraSubmissionRequest { 56 let scope = TeraComposerScope(authorPublicKey: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", localNetworkID: "nearby") 57 var editing = TeraAddForm.empty(.createPhotoUpdate) 58 editing.content = "Renewal fixture" 59 editing.media = [media] 60 let saved = try await backend.saveComposer(request: .init(scope: scope, id: backend.reserveComposerID(), 61 expectedRevision: nil, editSequence: 1, form: TeraComposerForm(editing: editing))) 62 return try await TeraSubmissionRequest(commandID: backend.reserveSubmissionID(), scope: scope, 63 composerID: saved.draft.id, expectedRevision: saved.draft.revision) 64 } 65 }