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 }