mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 06:45:18 +00:00
* Add geohash bookmarks: persistence, sampling integration, and UI\n\n- Add GeohashBookmarksStore with UserDefaults persistence and toggle API\n- Sample union of regional + bookmarked geohashes for activity notifications\n- LocationChannelsSheet: bookmark icons on nearby rows and a Bookmarked section\n- Header toolbar: toggle bookmark for current geohash\n- Tests: GeohashBookmarksStoreTests for normalization and persistence\n\nRationale: Bookmarked geohashes are always sampled for new activity notifications and quickly selectable from the sheet. * Notifications: remove background 'new chats!' nudge; geohash activity only on zero→alive; mesh 'nearby' only on zero→alive\n\n- Geohash sampling: notify only when previous participant count in last 5m was zero, with 30s freshness gate\n- Suppress old sampled events after (re)subscribe\n- Remove channel inactivity nudge\n- Mesh: reset rising-edge gate immediately when peer list goes empty (strict zero→alive) * Geohash notifications: ensure triggering message appears\n\n- On zero→alive sampling, pre-populate geoTimelines[gh] with the triggering message\n- Dedup on per-geohash timeline and UI messages by message ID to avoid duplicates after subscribe\n- Keeps participant update, block/self checks, and cooldown intact --------- Co-authored-by: jack <jackjackbits@users.noreply.github.com>
52 lines
1.6 KiB
Swift
52 lines
1.6 KiB
Swift
import XCTest
|
|
@testable import bitchat
|
|
|
|
final class GeohashBookmarksStoreTests: XCTestCase {
|
|
let storeKey = "locationChannel.bookmarks"
|
|
|
|
override func setUp() {
|
|
super.setUp()
|
|
// Clear persisted state before each test
|
|
UserDefaults.standard.removeObject(forKey: storeKey)
|
|
GeohashBookmarksStore.shared._resetForTesting()
|
|
}
|
|
|
|
override func tearDown() {
|
|
// Clean after each test
|
|
UserDefaults.standard.removeObject(forKey: storeKey)
|
|
GeohashBookmarksStore.shared._resetForTesting()
|
|
super.tearDown()
|
|
}
|
|
|
|
func testToggleAndNormalize() {
|
|
let store = GeohashBookmarksStore.shared
|
|
// Start clean
|
|
XCTAssertTrue(store.bookmarks.isEmpty)
|
|
|
|
// Add with mixed case and hash prefix
|
|
store.toggle("#U4PRUY")
|
|
XCTAssertTrue(store.isBookmarked("u4pruy"))
|
|
XCTAssertEqual(store.bookmarks.first, "u4pruy")
|
|
|
|
// Toggling again removes
|
|
store.toggle("u4pruy")
|
|
XCTAssertFalse(store.isBookmarked("u4pruy"))
|
|
XCTAssertTrue(store.bookmarks.isEmpty)
|
|
}
|
|
|
|
func testPersistenceWritten() throws {
|
|
let store = GeohashBookmarksStore.shared
|
|
store.toggle("ezs42")
|
|
store.toggle("u4pruy")
|
|
|
|
// Verify persisted JSON contains both (order not enforced here)
|
|
guard let data = UserDefaults.standard.data(forKey: storeKey) else {
|
|
XCTFail("No persisted data found")
|
|
return
|
|
}
|
|
let arr = try JSONDecoder().decode([String].self, from: data)
|
|
XCTAssertTrue(arr.contains("ezs42"))
|
|
XCTAssertTrue(arr.contains("u4pruy"))
|
|
}
|
|
}
|