1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package social.grain
import kotlinx.serialization.json.Json
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Test
import social.grain.data.api.SearchProfilesResponse
/**
* Profile search reuses ActorListItem, the same model the follower and
* favourite lists decode into. A field typed wrong breaks all of them at once.
* The fixture is a real response from the appview.
*/
class SearchDecodeTest {
private val json = Json {
ignoreUnknownKeys = true
explicitNulls = false
coerceInputValues = true
}
@Test
fun `a real profile search response decodes`() {
val fixture = """
{
"items": [
{
"did": "did:plc:bcgltzqazw5tb6k2g3ttenbj",
"handle": "chadtmiller.com",
"displayName": "chad",
"description": "building @grain.social, suuuup",
"avatar": "https://cdn.grain.social/x/avatar/plain/did:plc:bcgltzqazw5tb6k2g3ttenbj/y"
}
],
"cursor": "abc"
}
""".trimIndent()
val response = json.decodeFromString<SearchProfilesResponse>(fixture)
val profile = response.items!!.single()
assertEquals("chadtmiller.com", profile.handle)
assertEquals("chad", profile.displayName)
assertTrue(profile.avatar!!.startsWith("https://"))
assertEquals("abc", response.cursor)
}
@Test
fun `no matches decodes to an empty list rather than failing`() {
val response = json.decodeFromString<SearchProfilesResponse>("""{"items":[]}""")
assertTrue(response.items!!.isEmpty())
assertNull(response.cursor)
}
@Test
fun `a result missing optional fields decodes`() {
val response = json.decodeFromString<SearchProfilesResponse>(
"""{"items":[{"did":"did:plc:sparse","handle":"sparse.test"}]}""",
)
val profile = response.items!!.single()
assertNull(profile.displayName)
assertNull(profile.description)
}
}