field_ios

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

TeraScopedStoreTests.swift (5611B)


      1 @testable import TeraApp
      2 import XCTest
      3 
      4 @MainActor
      5 final class TeraScopedStoreTests: XCTestCase {
      6   func testTodayReconfigurationClearsOldCardsSynchronouslyAndRejectsLatePages() async throws {
      7     let backend = try TeraScopeBackend()
      8     let client = try await TeraScopeFixtures.client(backend)
      9     let store = TeraTodayStore(runtimeClient: client, clock: .fixed(unixSeconds: 1))
     10     store.configure(snapshot: TeraScopeFixtures.snapshot())
     11     await store.reload(refreshProjection: false)
     12     XCTAssertEqual(store.cards.map(\.id), ["wss://first.example"])
     13     let pause = await backend.pause(.page)
     14     let old = Task { await store.reload(refreshProjection: false) }
     15     await pause.entered.wait()
     16     store.configure(snapshot: TeraScopeFixtures.snapshot(account: "b", relay: "second"))
     17     XCTAssertTrue(store.cards.isEmpty)
     18     XCTAssertEqual(store.selectedContext?.relayURLs, ["wss://second.example"])
     19     await store.reload(refreshProjection: false)
     20     await pause.resume.open()
     21     await old.value
     22     XCTAssertEqual(store.cards.map(\.id), ["wss://second.example"])
     23     XCTAssertEqual(store.presentation.content, .available)
     24     store.stop()
     25     _ = try await client.stop()
     26   }
     27 
     28   func testLateRefreshFailureDoesNotIssueAnOldScopePageOrChangeNewState() async throws {
     29     let backend = try TeraScopeBackend()
     30     let client = try await TeraScopeFixtures.client(backend)
     31     let store = TeraTodayStore(runtimeClient: client, clock: .fixed(unixSeconds: 1))
     32     store.configure(snapshot: TeraScopeFixtures.snapshot())
     33     let pause = await backend.pause(.refresh, fails: true)
     34     let old = Task { await store.reload() }
     35     await pause.entered.wait()
     36     store.configure(snapshot: TeraScopeFixtures.snapshot(relay: "second"))
     37     await store.reload(refreshProjection: false)
     38     let count = await backend.counts[.page]
     39     await pause.resume.open()
     40     await old.value
     41     let after = await backend.counts[.page]
     42     XCTAssertEqual(after, count)
     43     XCTAssertEqual(store.cards.map(\.id), ["wss://second.example"])
     44     XCTAssertEqual(store.presentation.content, .available)
     45     store.stop()
     46     _ = try await client.stop()
     47   }
     48 
     49   func testSearchQueryEditsRejectLateSuccessAndFailureWithoutAnotherSearch() async throws {
     50     for fails in [false, true] {
     51       let backend = try TeraScopeBackend()
     52       let client = try await TeraScopeFixtures.client(backend)
     53       let store = TeraSearchStore(runtimeClient: client, clock: .fixed(unixSeconds: 1))
     54       store.configure(context: .defaultContext(snapshot: TeraScopeFixtures.snapshot()))
     55       store.updateQuery("old")
     56       let pause = await backend.pause(.search, fails: fails)
     57       let old = Task { await store.search() }
     58       await pause.entered.wait()
     59       store.updateQuery("new")
     60       await pause.resume.open()
     61       await old.value
     62       XCTAssertEqual(store.query, "new")
     63       XCTAssertTrue(store.results.isEmpty)
     64       XCTAssertEqual(store.state, .idle)
     65       _ = try await client.stop()
     66     }
     67   }
     68 
     69   func testAccountReconfigurationClearsSupportingStateAndRejectsLateMe() async throws {
     70     let backend = try TeraScopeBackend()
     71     let client = try await TeraScopeFixtures.client(backend)
     72     let stores = TeraProductStores(runtimeClient: client)
     73     let first = TeraScopeFixtures.snapshot()
     74     stores.configure(snapshot: first)
     75     stores.me.configure(context: .defaultContext(snapshot: first))
     76     stores.search.configure(context: .defaultContext(snapshot: first))
     77     stores.search.updateQuery("old")
     78     await stores.search.search()
     79     let pause = await backend.pause(.me)
     80     let old = Task { await stores.me.reload() }
     81     await pause.entered.wait()
     82     stores.settings.profileName = "Old account"
     83     let updated = TeraScopeFixtures.snapshot(account: "b", relay: "second")
     84     await backend.configure(updated)
     85     stores.configure(snapshot: updated)
     86     XCTAssertTrue(stores.search.results.isEmpty)
     87     XCTAssertEqual(stores.settings.profileName, "")
     88     await pause.resume.open()
     89     await old.value
     90     XCTAssertNil(stores.me.snapshot)
     91     XCTAssertEqual(stores.me.state, .idle)
     92     await stores.me.reload()
     93     let requested = await backend.lastMeContext
     94     XCTAssertEqual(requested, stores.today.selectedContext)
     95     XCTAssertEqual(stores.me.snapshot?.publicKey, updated.identity.publicKeyHex)
     96     stores.stop()
     97     _ = try await client.stop()
     98   }
     99 
    100   func testStoppedProductResumeCannotInstallLateStartupResults() async throws {
    101     let backend = try TeraScopeBackend()
    102     let client = try await TeraScopeFixtures.client(backend)
    103     let stores = TeraProductStores(runtimeClient: client)
    104     stores.configure(snapshot: TeraScopeFixtures.snapshot())
    105     let firstObserver = await backend.pause(.subscribe)
    106     let secondObserver = await backend.pause(.subscribe)
    107     let drafts = await backend.pause(.drafts)
    108     let pause = await backend.pause(.page)
    109     let old = Task { await stores.resume() }
    110     await pause.entered.wait()
    111     await drafts.entered.wait()
    112     let validated = stores.add.schemas
    113     XCTAssertEqual(validated.count, 5)
    114     stores.stop()
    115     await old.value
    116     XCTAssertTrue(stores.add.isProductReady)
    117     XCTAssertEqual(stores.add.schemas, validated)
    118     XCTAssertTrue(stores.add.drafts.isEmpty)
    119     XCTAssertEqual(stores.add.observationState, .stopped)
    120     let calls = await backend.counts[.drafts, default: 0]
    121     XCTAssertEqual(calls, 1)
    122     await pause.resume.open()
    123     await drafts.resume.open()
    124     await firstObserver.resume.open()
    125     await secondObserver.resume.open()
    126     _ = try await client.stop()
    127     XCTAssertEqual(stores.add.schemas, validated)
    128     XCTAssertTrue(stores.add.drafts.isEmpty)
    129   }
    130 }