From d89bfecd8c353bd0ed431997ea0655e3ca781b64 Mon Sep 17 00:00:00 2001 From: Taksh Date: Thu, 13 Aug 2026 06:36:39 +0530 Subject: [PATCH] Cover the bookmark name commit rules Pins the three cases the commit seam has to get right: a name resolved for a live bookmark is stored, and a name that lands after remove or after a panic clearAll is dropped, including across a reload from SharedPreferences. createForTest builds an isolated store with reverse geocoding disabled so the tests never reach the network. --- .../geohash/GeohashBookmarkNameCommitTest.kt | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 app/src/test/kotlin/com/bitchat/android/geohash/GeohashBookmarkNameCommitTest.kt diff --git a/app/src/test/kotlin/com/bitchat/android/geohash/GeohashBookmarkNameCommitTest.kt b/app/src/test/kotlin/com/bitchat/android/geohash/GeohashBookmarkNameCommitTest.kt new file mode 100644 index 00000000..b6c96e8b --- /dev/null +++ b/app/src/test/kotlin/com/bitchat/android/geohash/GeohashBookmarkNameCommitTest.kt @@ -0,0 +1,82 @@ +package com.bitchat.android.geohash + +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +/** + * A reverse geocode started for a bookmark runs on the IO dispatcher and can finish after + * the bookmark is gone. These tests pin the commit step: a resolved name is stored only + * while the geohash is still bookmarked. + */ +@RunWith(RobolectricTestRunner::class) +class GeohashBookmarkNameCommitTest { + + private lateinit var store: GeohashBookmarksStore + + @Before + fun setUp() { + val context = ApplicationProvider.getApplicationContext() + store = GeohashBookmarksStore.createForTest(context) + store.clearAll() + } + + @Test + fun `resolved name is stored for a bookmark that is still present`() { + store.add("u4pruy") + + store.commitResolvedName("u4pruy", "Copenhagen") + + assertEquals("Copenhagen", store.bookmarkNames.value["u4pruy"]) + } + + @Test + fun `resolved name is dropped when the bookmark was removed while in flight`() { + store.add("u4pruy") + store.remove("u4pruy") + + store.commitResolvedName("u4pruy", "Copenhagen") + + assertNull(store.bookmarkNames.value["u4pruy"]) + } + + @Test + fun `resolved name is dropped when a panic clear happened while in flight`() { + store.add("u4pruy") + store.clearAll() + + store.commitResolvedName("u4pruy", "Copenhagen") + + assertNull(store.bookmarkNames.value["u4pruy"]) + assertEquals(emptyMap(), store.bookmarkNames.value) + } + + @Test + fun `a panic clear survives a restart when a lookup lands after the wipe`() { + store.add("u4pruy") + store.clearAll() + store.commitResolvedName("u4pruy", "Copenhagen") + + // A fresh store reads back what was persisted, which is what the next launch sees. + val reloaded = GeohashBookmarksStore.createForTest( + ApplicationProvider.getApplicationContext() + ) + assertEquals(emptyList(), reloaded.bookmarks.value) + assertEquals(emptyMap(), reloaded.bookmarkNames.value) + } + + @Test + fun `an empty or blank name is never stored`() { + store.add("u4pruy") + + store.commitResolvedName("u4pruy", null) + store.commitResolvedName("u4pruy", "") + + assertNull(store.bookmarkNames.value["u4pruy"]) + } +}