field_ios

In-the-field app for Radroots on iOS
git clone https://radroots.dev/git/field_ios.git
Log | Files | Refs | README | LICENSE

TeraScopedAddTests.swift (8952B)


      1 @testable import TeraApp
      2 import XCTest
      3 
      4 @MainActor
      5 final class TeraScopedAddTests: XCTestCase {
      6   func testServiceProbeCompletionCannotChangeReplacementScopeOrClearItsProbe() async throws {
      7     for fails in [false, true] {
      8       let backend = try TeraScopeBackend()
      9       let client = try await TeraScopeFixtures.client(backend)
     10       let store = TeraAddStore(runtimeClient: client)
     11       store.configure(snapshot: TeraScopeFixtures.snapshot())
     12       let first = await backend.pause(.probe, fails: fails)
     13       let old = Task { await store.checkPhotoService() }
     14       await first.entered.wait()
     15       let updated = TeraScopeFixtures.snapshot(account: "b", relay: "second")
     16       await backend.configure(updated)
     17       store.configure(snapshot: updated)
     18       let second = await backend.pause(.probe)
     19       let current = Task { await store.checkPhotoService() }
     20       await second.entered.wait()
     21       await first.resume.open()
     22       await old.value
     23       XCTAssertTrue(store.isCheckingBlossom)
     24       XCTAssertNil(store.blossomEvidence)
     25       XCTAssertNil(store.message)
     26       await second.resume.open()
     27       await current.value
     28       XCTAssertEqual(store.blossomEvidence?.configFingerprint, "second")
     29       XCTAssertFalse(store.isCheckingBlossom)
     30       _ = try await client.stop()
     31     }
     32   }
     33 
     34   func testLateDraftStartupCannotPopulateAReplacementAccount() async throws {
     35     let backend = try TeraScopeBackend()
     36     let client = try await TeraScopeFixtures.client(backend)
     37     let store = TeraAddStore(runtimeClient: client)
     38     store.configure(snapshot: TeraScopeFixtures.snapshot())
     39     let pause = await backend.pause(.drafts)
     40     let old = Task { await store.start() }
     41     await pause.entered.wait()
     42     store.configure(snapshot: TeraScopeFixtures.snapshot(account: "b"))
     43     await backend.setDrafts([TeraScopeFixtures.draft("new")])
     44     await store.start()
     45     await pause.resume.open()
     46     await old.value
     47     XCTAssertEqual(store.drafts.first?.form?.content, "new")
     48     XCTAssertEqual(store.state, .ready)
     49     store.stop()
     50     _ = try await client.stop()
     51   }
     52 
     53   func testLegacyFormEditDuringSubmitKeepsTheNewFormAndRetainsDurableOldReceipt() async throws {
     54     let backend = try TeraScopeBackend()
     55     let client = try await TeraScopeFixtures.client(backend)
     56     let store = TeraAddStore(runtimeClient: client)
     57     store.configure(snapshot: TeraScopeFixtures.snapshot())
     58     await store.start()
     59     store.reopen(TeraScopeFixtures.draft("legacy source"))
     60     await TeraScopeFixtures.eventually { !store.protection.isWorking }
     61     store.updateForm(\.content, "saved version")
     62     let pause = await backend.pause(.save)
     63     let old = Task { await store.submit() }
     64     await pause.entered.wait()
     65     store.updateForm(\.content, "new edit")
     66     await pause.resume.open()
     67     await old.value
     68     XCTAssertEqual(store.form.content, "new edit")
     69     XCTAssertEqual(store.activeDraft?.form?.content, "legacy source")
     70     XCTAssertNil(store.message)
     71     XCTAssertFalse(store.isWorking)
     72     let durable = try await client.draftHeads(limit: 100)
     73     XCTAssertEqual(durable.first?.form?.content, "saved version")
     74     await store.submit()
     75     XCTAssertEqual(store.activeDraft?.form?.content, "new edit")
     76     store.stop()
     77     _ = try await client.stop()
     78   }
     79 
     80   func testLegacyLateFailureSnapshotCannotWriteItsMessageOrClearANewerOperation() async throws {
     81     let backend = try TeraScopeBackend()
     82     let client = try await TeraScopeFixtures.client(backend)
     83     let store = TeraAddStore(runtimeClient: client)
     84     store.configure(snapshot: TeraScopeFixtures.snapshot())
     85     await store.start()
     86     store.reopen(TeraScopeFixtures.draft("legacy source"))
     87     await TeraScopeFixtures.eventually { !store.protection.isWorking }
     88     let save = await backend.pause(.save, fails: true)
     89     let old = Task { await store.submit() }
     90     await save.entered.wait()
     91     let snapshot = await backend.pause(.snapshot)
     92     await save.resume.open()
     93     await snapshot.entered.wait()
     94     let updated = TeraScopeFixtures.snapshot(account: "b")
     95     await backend.configure(updated)
     96     store.configure(snapshot: updated)
     97     await store.start()
     98     store.reopen(TeraScopeFixtures.draft("legacy replacement"))
     99     await TeraScopeFixtures.eventually { !store.protection.isWorking }
    100     store.updateForm(\.content, "new account")
    101     let next = await backend.pause(.save)
    102     let current = Task { await store.submit() }
    103     await next.entered.wait()
    104     await snapshot.resume.open()
    105     await old.value
    106     XCTAssertTrue(store.isWorking)
    107     XCTAssertNil(store.message)
    108     XCTAssertNil(store.lastFailureCode)
    109     await next.resume.open()
    110     await current.value
    111     XCTAssertEqual(store.activeDraft?.form?.content, "new account")
    112     store.stop()
    113     _ = try await client.stop()
    114   }
    115 
    116   func testOldDraftObserverCannotOverwriteOrReportFailureInNewAccount() async throws {
    117     for fails in [false, true] {
    118       let backend = try TeraScopeBackend()
    119       let client = try await TeraScopeFixtures.client(backend)
    120       let store = TeraAddStore(runtimeClient: client)
    121       store.configure(snapshot: TeraScopeFixtures.snapshot())
    122       await store.start()
    123       await TeraScopeFixtures.eventually { store.observationState == .active }
    124       let tokens = await backend.tokens
    125       let oldToken = try XCTUnwrap(tokens.first)
    126       let pause = await backend.pause(.drafts, fails: fails)
    127       await backend.emit(.drafts)
    128       await pause.entered.wait()
    129       store.configure(snapshot: TeraScopeFixtures.snapshot(account: "b"))
    130       await backend.setDrafts([TeraScopeFixtures.draft("new account")])
    131       await store.start()
    132       await pause.resume.open()
    133       await oldToken.cancelled.wait()
    134       XCTAssertEqual(store.drafts.first?.form?.content, "new account")
    135       XCTAssertNil(store.message)
    136       store.stop()
    137       _ = try await client.stop()
    138     }
    139   }
    140 
    141   func testLateStartupInventoryCannotOverwriteANewerObserverSnapshot() async throws {
    142     let backend = try TeraScopeBackend()
    143     let client = try await TeraScopeFixtures.client(backend)
    144     let store = TeraAddStore(runtimeClient: client)
    145     store.configure(snapshot: TeraScopeFixtures.snapshot())
    146     let schemas = await backend.pause(.schemas)
    147     let startup = Task { await store.start() }
    148     await schemas.entered.wait()
    149     await TeraScopeFixtures.eventually { store.observationState == .active }
    150     await TeraScopeFixtures.eventually { store.drafts.first?.revision == 1 }
    151     let pause = await backend.pause(.drafts)
    152     await schemas.resume.open()
    153     await pause.entered.wait()
    154     await backend.setDrafts([TeraScopeFixtures.draft("new revision", revision: 2)])
    155     await backend.emit(.drafts)
    156     await TeraScopeFixtures.eventually { store.drafts.first?.revision == 2 }
    157     await pause.resume.open()
    158     await startup.value
    159     XCTAssertEqual(store.drafts.first?.revision, 2)
    160     XCTAssertEqual(store.state, .ready)
    161     store.stop()
    162     _ = try await client.stop()
    163   }
    164 
    165   func testLateProbeCannotOverwriteNewerServiceSnapshotInTheSameScope() async throws {
    166     let backend = try TeraScopeBackend()
    167     let client = try await TeraScopeFixtures.client(backend)
    168     let store = TeraAddStore(runtimeClient: client)
    169     store.configure(snapshot: TeraScopeFixtures.snapshot())
    170     await store.start()
    171     await TeraScopeFixtures.eventually { store.observationState == .active }
    172     let pause = await backend.pause(.probe)
    173     let old = Task { await store.checkPhotoService() }
    174     await pause.entered.wait()
    175     let evidence = TeraScopeFixtures.evidence(observedAt: 2)
    176     await backend.configure(TeraScopeFixtures.snapshot(evidence: evidence))
    177     await backend.emit(.settings)
    178     await TeraScopeFixtures.eventually { store.blossomEvidence == evidence }
    179     await pause.resume.open()
    180     await old.value
    181     XCTAssertEqual(store.blossomEvidence, evidence)
    182     XCTAssertFalse(store.isCheckingBlossom)
    183     store.stop()
    184     _ = try await client.stop()
    185   }
    186 
    187   func testLegacyLateFailureSnapshotCannotOverwriteEditedFormMessage() async throws {
    188     let backend = try TeraScopeBackend()
    189     let client = try await TeraScopeFixtures.client(backend)
    190     let store = TeraAddStore(runtimeClient: client)
    191     store.configure(snapshot: TeraScopeFixtures.snapshot())
    192     await store.start()
    193     store.reopen(TeraScopeFixtures.draft("legacy source"))
    194     await TeraScopeFixtures.eventually { !store.protection.isWorking }
    195     let save = await backend.pause(.save, fails: true)
    196     let old = Task { await store.submit() }
    197     await save.entered.wait()
    198     let snapshot = await backend.pause(.snapshot)
    199     await save.resume.open()
    200     await snapshot.entered.wait()
    201     store.updateForm(\.content, "New edit while error recovery waits")
    202     await snapshot.resume.open()
    203     await old.value
    204     XCTAssertNil(store.message)
    205     XCTAssertNil(store.lastFailureCode)
    206     XCTAssertEqual(store.form.content, "New edit while error recovery waits")
    207     XCTAssertFalse(store.isWorking)
    208     store.stop()
    209     _ = try await client.stop()
    210   }
    211 }