Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
Kotlin
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145package social.grain
import org.junit.Assert.assertEqualsimport org.junit.Assert.assertFalseimport org.junit.Assert.assertTrueimport org.junit.Testimport social.grain.data.model.GrainNotificationimport social.grain.data.model.GrainProfileimport social.grain.data.model.GroupedNotificationimport java.time.Instant
/** * Grouping is what turns a wall of "X favorited your gallery" into one row. * Getting it wrong either buries real events or merges things that aren't the * same event, and neither is visible from the code alone. */class NotificationGroupingTest {
private val base = Instant.parse("2026-08-21T12:00:00.000Z")
private fun notif( uri: String, reason: String, author: String, gallery: String? = null, hoursAgo: Long = 0, ) = GrainNotification( uri = uri, reason = reason, createdAt = base.minusSeconds(hoursAgo * 3600).toString(), author = GrainProfile(did = "did:plc:$author", handle = "$author.test"), galleryUri = gallery, )
@Test fun `favorites on the same gallery collapse into one row`() { val groups = GroupedNotification.group( listOf( notif("at://1", "gallery-favorite", "alice", gallery = "at://g/1"), notif("at://2", "gallery-favorite", "bob", gallery = "at://g/1", hoursAgo = 1), notif("at://3", "gallery-favorite", "carol", gallery = "at://g/1", hoursAgo = 2), ), )
assertEquals(1, groups.size) assertEquals(3, groups.single().authorCount) assertTrue(groups.single().isGrouped) }
@Test fun `favorites on different galleries stay separate`() { val groups = GroupedNotification.group( listOf( notif("at://1", "gallery-favorite", "alice", gallery = "at://g/1"), notif("at://2", "gallery-favorite", "bob", gallery = "at://g/2"), ), ) assertEquals(2, groups.size) }
@Test fun `the same person favoriting twice is counted once`() { val groups = GroupedNotification.group( listOf( notif("at://1", "gallery-favorite", "alice", gallery = "at://g/1"), notif("at://2", "gallery-favorite", "alice", gallery = "at://g/1", hoursAgo = 1), ), ) assertEquals(1, groups.size) assertEquals(1, groups.single().authorCount) }
@Test fun `events more than two days apart are separate rows`() { val groups = GroupedNotification.group( listOf( notif("at://1", "gallery-favorite", "alice", gallery = "at://g/1"), notif("at://2", "gallery-favorite", "bob", gallery = "at://g/1", hoursAgo = 72), ), ) assertEquals("a favorite three days later is its own event", 2, groups.size) }
@Test fun `follows group across subjects because they have none`() { val groups = GroupedNotification.group( listOf( notif("at://1", "follow", "alice"), notif("at://2", "follow", "bob", hoursAgo = 1), ), ) assertEquals(1, groups.size) assertEquals(2, groups.single().authorCount) }
@Test fun `comments never group even on the same gallery`() { // Each comment carries its own text; collapsing them would hide it. val groups = GroupedNotification.group( listOf( notif("at://1", "gallery-comment", "alice", gallery = "at://g/1"), notif("at://2", "gallery-comment", "bob", gallery = "at://g/1"), ), ) assertEquals(2, groups.size) assertTrue(groups.all { !it.isGrouped }) }
@Test fun `a favorite and a comment on one gallery do not merge`() { val groups = GroupedNotification.group( listOf( notif("at://1", "gallery-favorite", "alice", gallery = "at://g/1"), notif("at://2", "gallery-comment", "bob", gallery = "at://g/1"), ), ) assertEquals(2, groups.size) }
@Test fun `merging a page extends existing groups rather than reordering`() { val groups = GroupedNotification.group( listOf(notif("at://1", "gallery-favorite", "alice", gallery = "at://g/1")), ).toMutableList()
GroupedNotification.merge( listOf(notif("at://2", "gallery-favorite", "bob", gallery = "at://g/1", hoursAgo = 1)), groups, )
assertEquals(1, groups.size) assertEquals(2, groups.single().authorCount) assertEquals("the original stays the group's head", "at://1", groups.single().notification.uri) }
@Test fun `an unknown reason still renders as its own row`() { val groups = GroupedNotification.group( listOf(notif("at://1", "something-new-from-the-server", "alice")), ) assertEquals(1, groups.size) assertFalse(groups.single().isGrouped) }}