TeraRuntimeInvalidationTests.swift (5015B)
1 @testable import TeraApp 2 import TeraKitBindings 3 import XCTest 4 5 final class TeraRuntimeInvalidationTests: XCTestCase { 6 func testClientRejectsWrongAuthorityAndOldRevisionsWithoutRejectingOtherDomains() async throws { 7 let harness = RuntimeHarness() 8 let client = TeraRuntimeClient(factory: harness.start) 9 let configuration = TeraRuntimeClientTests().makeConfiguration(generation: "66") 10 _ = try await client.start(configuration: configuration) 11 let stream = try await client.changes(bufferCapacity: 8) 12 await harness.emit(change(revision: 2)) 13 for schema in [UInt16(1), UInt16(2), UInt16(4)] { 14 await harness.emit(change(revision: 9, schema: schema)) 15 } 16 await harness.emit(change(revision: 9, account: "bb")) 17 await harness.emit(change(revision: 9, storage: "cc")) 18 await harness.emit(change(revision: 9, epoch: "2")) 19 await harness.emit(change(revision: 9, epoch: "g")) 20 await harness.emit(change(revision: 2)) 21 await harness.emit(change(revision: 1)) 22 await harness.emit(change(revision: 1, kind: .media)) 23 await harness.emit(change(revision: 3)) 24 await harness.emit(change(revision: nil)) 25 await harness.emit(change(revision: .max)) 26 await harness.emit(change(revision: nil)) 27 _ = try await client.stop() 28 var received: [TeraRuntimeChange] = [] 29 for await value in stream { 30 received.append(value) 31 } 32 XCTAssertEqual(received.map(\.kind), [.today, .media, .today, .today, .today]) 33 XCTAssertEqual(received.map(\.revision.rawValue), [2, 1, 3, nil, nil]) 34 } 35 36 func testNewSubscriptionAdmitsItsOwnEpochAndDoesNotReuseOldWatermarks() async throws { 37 let harness = RuntimeHarness() 38 let client = TeraRuntimeClient(factory: harness.start) 39 _ = try await client.start(configuration: TeraRuntimeClientTests().makeConfiguration(generation: "66")) 40 let first = try await client.changes() 41 await harness.emit(change(revision: .max)) 42 let second = try await client.changes() 43 await harness.emit(change(revision: 1, epoch: "2")) 44 _ = try await client.stop() 45 var firstValues: [TeraRuntimeChange] = [] 46 var secondValues: [TeraRuntimeChange] = [] 47 for await value in first { 48 firstValues.append(value) 49 } 50 for await value in second { 51 secondValues.append(value) 52 } 53 XCTAssertEqual(firstValues, [change(revision: .max)]) 54 XCTAssertEqual(secondValues, [change(revision: 1, epoch: "2")]) 55 } 56 57 func testGeneratedWireRoundTripPreservesBothRevisionStatesAndFullScope() throws { 58 let configuration = TeraRuntimeClientTests().makeConfiguration(generation: "66") 59 for revision in [FfiInvalidationRevision.current(value: .max), .exhausted] { 60 let record = generated(revision: revision) 61 let decoded = try FfiConverterTypeFfiRuntimeChangeRecord_lift( 62 FfiConverterTypeFfiRuntimeChangeRecord_lower(record) 63 ) 64 XCTAssertEqual(decoded, record) 65 let value = decoded.appValue 66 XCTAssertTrue(value.matches(configuration)) 67 XCTAssertEqual(value.scope.context?.label, "Marché 農") 68 XCTAssertEqual(value.scope.context?.generation, UInt64.max) 69 XCTAssertEqual(value.entityID, "draft") 70 XCTAssertEqual(value.revision.rawValue, revision == .exhausted ? nil : UInt64.max) 71 XCTAssertTrue(value.matches(context: value.scope.context)) 72 XCTAssertFalse(value.matches(context: nil)) 73 let other = TeraLocalNetwork( 74 schemaVersion: 1, id: "local", label: "Marché 農", relayURLs: ["wss://other.example"], 75 locality: "Town", followedAuthors: [String(repeating: "c", count: 64)], generation: .max 76 ) 77 XCTAssertFalse(value.matches(context: other)) 78 XCTAssertTrue(change(revision: 1).matches(context: other)) 79 } 80 } 81 82 private func change( 83 revision: UInt64?, kind: TeraRuntimeChangeKind = .today, schema: UInt16 = 3, 84 account: String = "66", storage: String = "66", epoch: String = "1" 85 ) -> TeraRuntimeChange { 86 TeraRuntimeChange( 87 schemaVersion: schema, 88 scope: TeraRuntimeChangeScope( 89 publicKey: String(repeating: account, count: 32), 90 sourceGeneration: String(repeating: storage, count: 32), context: nil 91 ), 92 epoch: String(repeating: epoch, count: 32), revision: TeraProjectionRevision(rawValue: revision), 93 delivery: .change, kind: kind, entityID: nil 94 ) 95 } 96 97 private func generated(revision: FfiInvalidationRevision) -> FfiRuntimeChangeRecord { 98 FfiRuntimeChangeRecord( 99 schemaVersion: 3, 100 scope: FfiRuntimeChangeScope( 101 publicKey: String(repeating: "66", count: 32), 102 sourceGeneration: String(repeating: "66", count: 32), 103 context: FfiLocalNetworkRecord( 104 schemaVersion: 1, id: "local", label: "Marché 農", relayUrls: ["wss://relay.example"], 105 locality: "Town", followedAuthors: [String(repeating: "c", count: 64)], generation: .max 106 ) 107 ), 108 epoch: String(repeating: "1", count: 32), revision: revision, delivery: .change, kind: .today, entityId: "draft" 109 ) 110 } 111 }