refactor(quartz): rename FavoriteDvmListEvent -> FavoriteAlgoFeedsListEvent

The list event only stores content-discovery feeds (kind-5300 DVMs),
not every DVM, so the old name was misleading. Rename the wire-level
type to reflect what's actually in it.

- Quartz: package nip51Lists.favoriteDvmList -> favoriteAlgoFeedsList;
  class FavoriteDvmListEvent -> FavoriteAlgoFeedsListEvent.
- DSL helpers renamed: favoriteDvm/favoriteDvms builder extensions ->
  favoriteAlgoFeed/favoriteAlgoFeeds; TagArray.favoriteDvmList/Set ->
  favoriteAlgoFeedsList/Set.
- create/add/remove parameter names dvm -> feed, publicDvms/privateDvms
  -> publicFeeds/privateFeeds; public/private accessors
  publicFavoriteDvms/privateFavoriteDvms -> publicFavoriteAlgoFeeds/
  privateFavoriteAlgoFeeds. ALT string updated.
- EventFactory + LocalCache dispatch branches + AccountSettings backup
  field type + FavoriteDvmListState + FavoriteDvmListDecryptionCache all
  import the new type. Internal amethyst-side classes
  (FavoriteDvmListState, FavoriteDvmListDecryptionCache), the top-nav
  filter classes (FavoriteDvm*, AllFavoriteDvms*) and the orchestrator
  keep their names — they still deal with content-discovery DVMs
  specifically, and the narrower rename here is scoped to the Nostr
  wire format the user was asking about.
- Quartz test renamed + rewired. Build + tests green on both modules.
This commit is contained in:
Claude
2026-04-19 17:37:55 +00:00
parent fc284e3cfe
commit 72598026a3
9 changed files with 86 additions and 86 deletions
@@ -43,7 +43,7 @@ import com.vitorpamplona.quartz.nip37Drafts.privateOutbox.PrivateOutboxRelayList
import com.vitorpamplona.quartz.nip42RelayAuth.RelayAuthEvent
import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
import com.vitorpamplona.quartz.nip51Lists.favoriteDvmList.FavoriteDvmListEvent
import com.vitorpamplona.quartz.nip51Lists.favoriteAlgoFeedsList.FavoriteAlgoFeedsListEvent
import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListEvent
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
import com.vitorpamplona.quartz.nip51Lists.muteList.MuteListEvent
@@ -203,7 +203,7 @@ class AccountSettings(
var backupChannelList: ChannelListEvent? = null,
var backupCommunityList: CommunityListEvent? = null,
var backupHashtagList: HashtagListEvent? = null,
var backupFavoriteDvmList: FavoriteDvmListEvent? = null,
var backupFavoriteDvmList: FavoriteAlgoFeedsListEvent? = null,
var backupGeohashList: GeohashListEvent? = null,
var backupEphemeralChatList: EphemeralChatListEvent? = null,
var backupTrustProviderList: TrustProviderListEvent? = null,
@@ -727,7 +727,7 @@ class AccountSettings(
}
}
fun updateFavoriteDvmListTo(newFavoriteDvmList: FavoriteDvmListEvent?) {
fun updateFavoriteDvmListTo(newFavoriteDvmList: FavoriteAlgoFeedsListEvent?) {
if (newFavoriteDvmList == null || newFavoriteDvmList.tags.isEmpty()) return
// Events might be different objects, we have to compare their ids.
@@ -149,7 +149,7 @@ import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
import com.vitorpamplona.quartz.nip51Lists.PinListEvent
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.BookmarkListEvent
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.OldBookmarkListEvent
import com.vitorpamplona.quartz.nip51Lists.favoriteDvmList.FavoriteDvmListEvent
import com.vitorpamplona.quartz.nip51Lists.favoriteAlgoFeedsList.FavoriteAlgoFeedsListEvent
import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent
import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListEvent
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
@@ -2636,7 +2636,7 @@ object LocalCache : ILocalCache, ICacheProvider {
is LiveChessGameEndEvent -> consumeBaseReplaceable(event, relay, wasVerified)
is LiveChessDrawOfferEvent -> consumeBaseReplaceable(event, relay, wasVerified)
is HashtagListEvent -> consumeBaseReplaceable(event, relay, wasVerified)
is FavoriteDvmListEvent -> consumeBaseReplaceable(event, relay, wasVerified)
is FavoriteAlgoFeedsListEvent -> consumeBaseReplaceable(event, relay, wasVerified)
is HighlightEvent -> consumeRegularEvent(event, relay, wasVerified)
is IndexerRelayListEvent -> consumeBaseReplaceable(event, relay, wasVerified)
is InteractiveStoryPrologueEvent -> consumeBaseReplaceable(event, relay, wasVerified)
@@ -22,15 +22,15 @@ package com.vitorpamplona.amethyst.model.nip51Lists.favoriteDvmLists
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEventCache
import com.vitorpamplona.quartz.nip51Lists.favoriteDvmList.FavoriteDvmListEvent
import com.vitorpamplona.quartz.nip51Lists.favoriteDvmList.favoriteDvmSet
import com.vitorpamplona.quartz.nip51Lists.favoriteAlgoFeedsList.FavoriteAlgoFeedsListEvent
import com.vitorpamplona.quartz.nip51Lists.favoriteAlgoFeedsList.favoriteAlgoFeedsSet
class FavoriteDvmListDecryptionCache(
val signer: NostrSigner,
) {
val cachedPrivateLists = PrivateTagArrayEventCache<FavoriteDvmListEvent>(signer)
val cachedPrivateLists = PrivateTagArrayEventCache<FavoriteAlgoFeedsListEvent>(signer)
fun cachedFavoriteDvms(event: FavoriteDvmListEvent) = cachedPrivateLists.mergeTagListPrecached(event).favoriteDvmSet()
fun cachedFavoriteDvms(event: FavoriteAlgoFeedsListEvent) = cachedPrivateLists.mergeTagListPrecached(event).favoriteAlgoFeedsSet()
suspend fun favoriteDvms(event: FavoriteDvmListEvent) = cachedPrivateLists.mergeTagList(event).favoriteDvmSet()
suspend fun favoriteDvms(event: FavoriteAlgoFeedsListEvent) = cachedPrivateLists.mergeTagList(event).favoriteAlgoFeedsSet()
}
@@ -28,7 +28,7 @@ import com.vitorpamplona.amethyst.model.NoteState
import com.vitorpamplona.quartz.nip01Core.core.Address
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark
import com.vitorpamplona.quartz.nip51Lists.favoriteDvmList.FavoriteDvmListEvent
import com.vitorpamplona.quartz.nip51Lists.favoriteAlgoFeedsList.FavoriteAlgoFeedsListEvent
import com.vitorpamplona.quartz.utils.Log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DelicateCoroutinesApi
@@ -53,14 +53,14 @@ class FavoriteDvmListState(
// Creates a long-term reference for this note so that the GC doesn't collect the note itself
val favoriteDvmListNote = cache.getOrCreateAddressableNote(getFavoriteDvmListAddress())
fun getFavoriteDvmListAddress() = FavoriteDvmListEvent.createAddress(signer.pubKey)
fun getFavoriteDvmListAddress() = FavoriteAlgoFeedsListEvent.createAddress(signer.pubKey)
fun getFavoriteDvmListFlow(): StateFlow<NoteState> = favoriteDvmListNote.flow().metadata.stateFlow
fun getFavoriteDvmList(): FavoriteDvmListEvent? = favoriteDvmListNote.event as? FavoriteDvmListEvent
fun getFavoriteDvmList(): FavoriteAlgoFeedsListEvent? = favoriteDvmListNote.event as? FavoriteAlgoFeedsListEvent
suspend fun favoriteDvmListWithBackup(note: Note): Set<Address> {
val event = note.event as? FavoriteDvmListEvent ?: settings.backupFavoriteDvmList
val event = note.event as? FavoriteAlgoFeedsListEvent ?: settings.backupFavoriteDvmList
return event?.let { decryptionCache.favoriteDvms(it) } ?: emptySet()
}
@@ -92,18 +92,18 @@ class FavoriteDvmListState(
emptyList(),
)
suspend fun follow(dvm: AddressBookmark): FavoriteDvmListEvent {
suspend fun follow(dvm: AddressBookmark): FavoriteAlgoFeedsListEvent {
val list = getFavoriteDvmList()
return if (list == null) {
FavoriteDvmListEvent.create(dvm, false, signer)
FavoriteAlgoFeedsListEvent.create(dvm, false, signer)
} else {
FavoriteDvmListEvent.add(list, dvm, false, signer)
FavoriteAlgoFeedsListEvent.add(list, dvm, false, signer)
}
}
suspend fun unfollow(dvm: Address): FavoriteDvmListEvent? {
suspend fun unfollow(dvm: Address): FavoriteAlgoFeedsListEvent? {
val list = getFavoriteDvmList() ?: return null
return FavoriteDvmListEvent.remove(list, dvm, signer)
return FavoriteAlgoFeedsListEvent.remove(list, dvm, signer)
}
init {
@@ -119,7 +119,7 @@ class FavoriteDvmListState(
Log.d("AccountRegisterObservers", "Favorite DVM List Collector Start")
getFavoriteDvmListFlow().collect {
Log.d("AccountRegisterObservers") { "Favorite DVM List for ${signer.pubKey}" }
(it.note.event as? FavoriteDvmListEvent)?.let {
(it.note.event as? FavoriteAlgoFeedsListEvent)?.let {
settings.updateFavoriteDvmListTo(it)
}
}
@@ -18,7 +18,7 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.quartz.nip51Lists.favoriteDvmList
package com.vitorpamplona.quartz.nip51Lists.favoriteAlgoFeedsList
import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.nip01Core.core.Address
@@ -38,7 +38,7 @@ import com.vitorpamplona.quartz.nip51Lists.remove
import com.vitorpamplona.quartz.utils.TimeUtils
@Immutable
class FavoriteDvmListEvent(
class FavoriteAlgoFeedsListEvent(
id: HexKey,
pubKey: HexKey,
createdAt: Long,
@@ -46,72 +46,72 @@ class FavoriteDvmListEvent(
content: String,
sig: HexKey,
) : PrivateTagArrayEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
fun publicFavoriteDvms(): List<AddressBookmark> = tags.mapNotNull(AddressBookmark::parse)
fun publicFavoriteAlgoFeeds(): List<AddressBookmark> = tags.mapNotNull(AddressBookmark::parse)
suspend fun privateFavoriteDvms(signer: NostrSigner): List<AddressBookmark>? = privateTags(signer)?.mapNotNull(AddressBookmark::parse)
suspend fun privateFavoriteAlgoFeeds(signer: NostrSigner): List<AddressBookmark>? = privateTags(signer)?.mapNotNull(AddressBookmark::parse)
companion object {
const val KIND = 10090
const val ALT = "Favorite DVM list"
const val ALT = "Favorite algo-feeds list"
const val FIXED_D_TAG = ""
fun createAddress(pubKey: HexKey) = Address(KIND, pubKey, FIXED_D_TAG)
suspend fun create(
dvm: AddressBookmark,
feed: AddressBookmark,
isPrivate: Boolean,
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
): FavoriteDvmListEvent =
): FavoriteAlgoFeedsListEvent =
if (isPrivate) {
create(
publicDvms = emptyList(),
privateDvms = listOf(dvm),
publicFeeds = emptyList(),
privateFeeds = listOf(feed),
signer = signer,
createdAt = createdAt,
)
} else {
create(
publicDvms = listOf(dvm),
privateDvms = emptyList(),
publicFeeds = listOf(feed),
privateFeeds = emptyList(),
signer = signer,
createdAt = createdAt,
)
}
suspend fun add(
earlierVersion: FavoriteDvmListEvent,
dvm: AddressBookmark,
earlierVersion: FavoriteAlgoFeedsListEvent,
feed: AddressBookmark,
isPrivate: Boolean,
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
): FavoriteDvmListEvent =
): FavoriteAlgoFeedsListEvent =
if (isPrivate) {
val privateTags =
earlierVersion.privateTags(signer)
?: throw SignerExceptions.UnauthorizedDecryptionException()
resign(
tags = earlierVersion.tags,
privateTags = privateTags.remove(dvm.toTagIdOnly()) + dvm.toTagArray(),
privateTags = privateTags.remove(feed.toTagIdOnly()) + feed.toTagArray(),
signer = signer,
createdAt = createdAt,
)
} else {
resign(
content = earlierVersion.content,
tags = earlierVersion.tags.remove(dvm.toTagIdOnly()) + dvm.toTagArray(),
tags = earlierVersion.tags.remove(feed.toTagIdOnly()) + feed.toTagArray(),
signer = signer,
createdAt = createdAt,
)
}
suspend fun remove(
earlierVersion: FavoriteDvmListEvent,
dvm: Address,
earlierVersion: FavoriteAlgoFeedsListEvent,
feed: Address,
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
): FavoriteDvmListEvent {
val idOnly = AddressBookmark.assemble(dvm, null)
): FavoriteAlgoFeedsListEvent {
val idOnly = AddressBookmark.assemble(feed, null)
val privateTags = earlierVersion.privateTags(signer)
return if (privateTags != null) {
resign(
@@ -147,7 +147,7 @@ class FavoriteDvmListEvent(
tags: TagArray,
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
): FavoriteDvmListEvent {
): FavoriteAlgoFeedsListEvent {
val newTags =
if (tags.fastAny(AltTag::match)) {
tags
@@ -159,32 +159,32 @@ class FavoriteDvmListEvent(
}
suspend fun create(
publicDvms: List<AddressBookmark> = emptyList(),
privateDvms: List<AddressBookmark> = emptyList(),
publicFeeds: List<AddressBookmark> = emptyList(),
privateFeeds: List<AddressBookmark> = emptyList(),
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
): FavoriteDvmListEvent {
val template = build(publicDvms, privateDvms, signer, createdAt)
): FavoriteAlgoFeedsListEvent {
val template = build(publicFeeds, privateFeeds, signer, createdAt)
return signer.sign(template)
}
suspend fun build(
publicDvms: List<AddressBookmark> = emptyList(),
privateDvms: List<AddressBookmark> = emptyList(),
publicFeeds: List<AddressBookmark> = emptyList(),
privateFeeds: List<AddressBookmark> = emptyList(),
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
initializer: TagArrayBuilder<FavoriteDvmListEvent>.() -> Unit = {},
) = eventTemplate<FavoriteDvmListEvent>(
initializer: TagArrayBuilder<FavoriteAlgoFeedsListEvent>.() -> Unit = {},
) = eventTemplate<FavoriteAlgoFeedsListEvent>(
kind = KIND,
description =
PrivateTagsInContent.encryptNip44(
privateDvms.map { it.toTagArray() }.toTypedArray(),
privateFeeds.map { it.toTagArray() }.toTypedArray(),
signer,
),
createdAt = createdAt,
) {
alt(ALT)
favoriteDvms(publicDvms)
favoriteAlgoFeeds(publicFeeds)
initializer()
}
@@ -18,11 +18,11 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.quartz.nip51Lists.favoriteDvmList
package com.vitorpamplona.quartz.nip51Lists.favoriteAlgoFeedsList
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark
fun TagArrayBuilder<FavoriteDvmListEvent>.favoriteDvm(app: AddressBookmark) = add(app.toTagArray())
fun TagArrayBuilder<FavoriteAlgoFeedsListEvent>.favoriteAlgoFeed(app: AddressBookmark) = add(app.toTagArray())
fun TagArrayBuilder<FavoriteDvmListEvent>.favoriteDvms(apps: List<AddressBookmark>) = addAll(apps.map { it.toTagArray() })
fun TagArrayBuilder<FavoriteAlgoFeedsListEvent>.favoriteAlgoFeeds(apps: List<AddressBookmark>) = addAll(apps.map { it.toTagArray() })
@@ -18,11 +18,11 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.quartz.nip51Lists.favoriteDvmList
package com.vitorpamplona.quartz.nip51Lists.favoriteAlgoFeedsList
import com.vitorpamplona.quartz.nip01Core.core.TagArray
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.AddressBookmark
fun TagArray.favoriteDvmList() = mapNotNull(AddressBookmark::parseAddress)
fun TagArray.favoriteAlgoFeedsList() = mapNotNull(AddressBookmark::parseAddress)
fun TagArray.favoriteDvmSet() = mapNotNullTo(mutableSetOf(), AddressBookmark::parseAddress)
fun TagArray.favoriteAlgoFeedsSet() = mapNotNullTo(mutableSetOf(), AddressBookmark::parseAddress)
@@ -134,7 +134,7 @@ import com.vitorpamplona.quartz.nip51Lists.appCurationSet.AppCurationSetEvent
import com.vitorpamplona.quartz.nip51Lists.articleCurationSet.ArticleCurationSetEvent
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.BookmarkListEvent
import com.vitorpamplona.quartz.nip51Lists.bookmarkList.OldBookmarkListEvent
import com.vitorpamplona.quartz.nip51Lists.favoriteDvmList.FavoriteDvmListEvent
import com.vitorpamplona.quartz.nip51Lists.favoriteAlgoFeedsList.FavoriteAlgoFeedsListEvent
import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent
import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListEvent
import com.vitorpamplona.quartz.nip51Lists.gitAuthorList.GitAuthorListEvent
@@ -423,7 +423,7 @@ class EventFactory {
GoodWikiAuthorListEvent.KIND -> GoodWikiAuthorListEvent(id, pubKey, createdAt, tags, content, sig)
GoodWikiRelayListEvent.KIND -> GoodWikiRelayListEvent(id, pubKey, createdAt, tags, content, sig)
GoalEvent.KIND -> GoalEvent(id, pubKey, createdAt, tags, content, sig)
FavoriteDvmListEvent.KIND -> FavoriteDvmListEvent(id, pubKey, createdAt, tags, content, sig)
FavoriteAlgoFeedsListEvent.KIND -> FavoriteAlgoFeedsListEvent(id, pubKey, createdAt, tags, content, sig)
HashtagListEvent.KIND -> HashtagListEvent(id, pubKey, createdAt, tags, content, sig)
HighlightEvent.KIND -> HighlightEvent(id, pubKey, createdAt, tags, content, sig)
HTTPAuthorizationEvent.KIND -> HTTPAuthorizationEvent(id, pubKey, createdAt, tags, content, sig)
@@ -18,7 +18,7 @@
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.quartz.nip51Lists.favoriteDvmList
package com.vitorpamplona.quartz.nip51Lists.favoriteAlgoFeedsList
import com.vitorpamplona.quartz.nip01Core.core.Address
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
@@ -30,7 +30,7 @@ import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
class FavoriteDvmListEventTest {
class FavoriteAlgoFeedsListEventTest {
private val signer = NostrSignerInternal("nsec10g0wheggqn9dawlc0yuv6adnat6n09anr7eyykevw2dm8xa5fffs0wsdsr".nsecToKeyPair())
private fun dvm(
@@ -40,12 +40,12 @@ class FavoriteDvmListEventTest {
@Test
fun kindMatchesSpec() {
assertEquals(10090, FavoriteDvmListEvent.KIND)
assertEquals(10090, FavoriteAlgoFeedsListEvent.KIND)
}
@Test
fun addressesAreReplaceableWithFixedDTag() {
val address = FavoriteDvmListEvent.createAddress("a".repeat(64))
val address = FavoriteAlgoFeedsListEvent.createAddress("a".repeat(64))
assertEquals(10090, address.kind)
assertEquals("", address.dTag)
}
@@ -53,11 +53,11 @@ class FavoriteDvmListEventTest {
@Test
fun createStoresDvmAsATag() =
runTest {
val dvm = dvm("a".repeat(64))
val aFeed = dvm("a".repeat(64))
val event =
FavoriteDvmListEvent.create(
dvm = dvm,
FavoriteAlgoFeedsListEvent.create(
feed = aFeed,
isPrivate = false,
signer = signer,
createdAt = 1740669816,
@@ -65,31 +65,31 @@ class FavoriteDvmListEventTest {
assertEquals(10090, event.kind)
assertTrue(
event.tags.any { it.size >= 2 && it[0] == "a" && it[1] == dvm.address.toValue() },
event.tags.any { it.size >= 2 && it[0] == "a" && it[1] == aFeed.address.toValue() },
"public a tag for the favourited DVM should be present",
)
val favorites = event.publicFavoriteDvms()
val favorites = event.publicFavoriteAlgoFeeds()
assertEquals(1, favorites.size)
assertEquals(dvm.address, favorites.first().address)
assertEquals(aFeed.address, favorites.first().address)
}
@Test
fun addAppendsWithoutDuplicatingExistingEntry() =
runTest {
val dvm = dvm("a".repeat(64))
val aFeed = dvm("a".repeat(64))
val initial =
FavoriteDvmListEvent.create(
dvm = dvm,
FavoriteAlgoFeedsListEvent.create(
feed = aFeed,
isPrivate = false,
signer = signer,
createdAt = 1740669816,
)
val afterDupeAdd =
FavoriteDvmListEvent.add(
FavoriteAlgoFeedsListEvent.add(
earlierVersion = initial,
dvm = dvm,
feed = aFeed,
isPrivate = false,
signer = signer,
createdAt = 1740669817,
@@ -97,7 +97,7 @@ class FavoriteDvmListEventTest {
assertEquals(
1,
afterDupeAdd.publicFavoriteDvms().count { it.address == dvm.address },
afterDupeAdd.publicFavoriteAlgoFeeds().count { it.address == aFeed.address },
"re-adding the same DVM must not produce a duplicate tag",
)
}
@@ -109,23 +109,23 @@ class FavoriteDvmListEventTest {
val second = dvm("b".repeat(64))
val initial =
FavoriteDvmListEvent.create(
dvm = first,
FavoriteAlgoFeedsListEvent.create(
feed = first,
isPrivate = false,
signer = signer,
createdAt = 1740669816,
)
val after =
FavoriteDvmListEvent.add(
FavoriteAlgoFeedsListEvent.add(
earlierVersion = initial,
dvm = second,
feed = second,
isPrivate = false,
signer = signer,
createdAt = 1740669817,
)
val addresses = after.publicFavoriteDvms().map { it.address }.toSet()
val addresses = after.publicFavoriteAlgoFeeds().map { it.address }.toSet()
assertTrue(first.address in addresses)
assertTrue(second.address in addresses)
}
@@ -137,22 +137,22 @@ class FavoriteDvmListEventTest {
val second = dvm("b".repeat(64))
val initial =
FavoriteDvmListEvent.create(
publicDvms = listOf(first, second),
privateDvms = emptyList(),
FavoriteAlgoFeedsListEvent.create(
publicFeeds = listOf(first, second),
privateFeeds = emptyList(),
signer = signer,
createdAt = 1740669816,
)
val after =
FavoriteDvmListEvent.remove(
FavoriteAlgoFeedsListEvent.remove(
earlierVersion = initial,
dvm = first.address,
feed = first.address,
signer = signer,
createdAt = 1740669817,
)
val addresses = after.publicFavoriteDvms().map { it.address }.toSet()
val addresses = after.publicFavoriteAlgoFeeds().map { it.address }.toSet()
assertFalse(first.address in addresses, "removed DVM should not survive")
assertTrue(second.address in addresses, "other DVMs should be preserved")
}