mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-26 17:05:21 +00:00
Fix panic wipe relay and geohash state
This commit is contained in:
@@ -1042,6 +1042,38 @@ struct ChatViewModelPanicTests {
|
||||
#expect(viewModel.unreadPrivateMessages.isEmpty)
|
||||
#expect(viewModel.selectedPrivateChatPeer == nil)
|
||||
}
|
||||
|
||||
@Test @MainActor
|
||||
func panicClearAllData_resetsLiveGeohashAndNostrState() async throws {
|
||||
let (viewModel, _) = makeTestableViewModel()
|
||||
let geohash = "u4pruy"
|
||||
let channel = GeohashChannel(level: .city, geohash: geohash)
|
||||
let identity = try NostrIdentity.generate()
|
||||
let pubkey = String(repeating: "ab", count: 32)
|
||||
let peerID = PeerID(nostr: pubkey)
|
||||
|
||||
viewModel.activeChannel = .location(channel)
|
||||
viewModel.setGeoChatSubscriptionID("geo-\(geohash)")
|
||||
viewModel.setGeoDmSubscriptionID("geo-dm-\(geohash)")
|
||||
viewModel.addGeoSamplingSub("geo-sample-\(geohash)", forGeohash: geohash)
|
||||
viewModel.cachedGeohashIdentity = (geohash, identity)
|
||||
viewModel.registerNostrKeyMapping(pubkey, for: peerID)
|
||||
viewModel.currentGeohash = geohash
|
||||
viewModel.geoNicknames = [pubkey: "alice"]
|
||||
viewModel.teleportedGeo = [pubkey]
|
||||
|
||||
viewModel.panicClearAllData()
|
||||
|
||||
#expect(viewModel.activeChannel == .mesh)
|
||||
#expect(viewModel.geoSubscriptionID == nil)
|
||||
#expect(viewModel.geoDmSubscriptionID == nil)
|
||||
#expect(viewModel.geoSamplingSubs.isEmpty)
|
||||
#expect(viewModel.cachedGeohashIdentity == nil)
|
||||
#expect(viewModel.nostrKeyMapping.isEmpty)
|
||||
#expect(viewModel.currentGeohash == nil)
|
||||
#expect(viewModel.geoNicknames.isEmpty)
|
||||
#expect(viewModel.teleportedGeo.isEmpty)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Service Lifecycle Tests
|
||||
|
||||
@@ -1328,6 +1328,49 @@ final class NostrRelayManagerTests: XCTestCase {
|
||||
XCTAssertEqual(context.manager.debugPendingSubscriptionCount(for: relayURL), 0)
|
||||
}
|
||||
|
||||
func test_resetForPanicWipe_dropsSessionRelayStateWithoutFiringCallbacks() async throws {
|
||||
let relayURL = "wss://panic-reset.example"
|
||||
let context = makeContext(permission: .denied, userTorEnabled: true, torEnforced: true, torIsReady: false)
|
||||
let event = try makeSignedEvent(content: "queued before panic")
|
||||
var handledEvents = 0
|
||||
var eoseCount = 0
|
||||
|
||||
context.manager.subscribe(
|
||||
filter: makeFilter(),
|
||||
id: "panic-sub",
|
||||
relayUrls: [relayURL],
|
||||
handler: { _ in handledEvents += 1 },
|
||||
onEOSE: { eoseCount += 1 }
|
||||
)
|
||||
context.manager.sendEvent(event, to: [relayURL])
|
||||
|
||||
XCTAssertEqual(context.manager.debugMessageHandlerCount, 1)
|
||||
XCTAssertEqual(context.manager.debugSubscriptionRequestCount, 1)
|
||||
XCTAssertEqual(context.manager.debugPendingSubscriptionCount(for: relayURL), 1)
|
||||
XCTAssertEqual(context.manager.debugPendingEOSECallbackCount, 1)
|
||||
XCTAssertEqual(context.manager.debugPendingMessageQueueCount, 1)
|
||||
XCTAssertTrue(context.sessionFactory.requestedURLs.isEmpty)
|
||||
|
||||
context.manager.resetForPanicWipe()
|
||||
|
||||
XCTAssertEqual(context.manager.debugMessageHandlerCount, 0)
|
||||
XCTAssertEqual(context.manager.debugSubscriptionRequestCount, 0)
|
||||
XCTAssertEqual(context.manager.debugPendingSubscriptionCount(for: relayURL), 0)
|
||||
XCTAssertEqual(context.manager.debugPendingEOSECallbackCount, 0)
|
||||
XCTAssertEqual(context.manager.debugPendingMessageQueueCount, 0)
|
||||
XCTAssertEqual(handledEvents, 0)
|
||||
XCTAssertEqual(eoseCount, 0)
|
||||
|
||||
// Stale Tor wait and fallback callbacks from the pre-wipe generation
|
||||
// must not resurrect connections or settle callbacks after reset.
|
||||
context.torWaiter.resolve(true)
|
||||
context.scheduler.runNext()
|
||||
try? await Task.sleep(nanoseconds: 20_000_000)
|
||||
|
||||
XCTAssertTrue(context.sessionFactory.requestedURLs.isEmpty)
|
||||
XCTAssertEqual(eoseCount, 0)
|
||||
}
|
||||
|
||||
func test_reconnectBackoff_appliesJitterWithinConfiguredBounds() async {
|
||||
let relayURL = "wss://jitter-bounds.example"
|
||||
// Pin the jitter source to the extremes and the midpoint of [0, 1).
|
||||
|
||||
Reference in New Issue
Block a user