Skip to content

Commit b82ac6c

Browse files
fix: normalize reaction encoding, support legacy form (#112)
* fix: normalize reaction encoding, support legacy form * fix linter issues --------- Co-authored-by: Naomi Plasterer <naomi@xmtp.com>
1 parent 3ec0620 commit b82ac6c

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

library/src/androidTest/java/org/xmtp/android/library/ReactionTest.kt

+46
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package org.xmtp.android.library
22

33
import androidx.test.ext.junit.runners.AndroidJUnit4
4+
import com.google.protobuf.kotlin.toByteStringUtf8
45
import org.junit.Assert.assertEquals
56
import org.junit.Test
67
import org.junit.runner.RunWith
78
import org.xmtp.android.library.codecs.ContentTypeReaction
9+
import org.xmtp.android.library.codecs.EncodedContent
810
import org.xmtp.android.library.codecs.Reaction
911
import org.xmtp.android.library.codecs.ReactionAction
1012
import org.xmtp.android.library.codecs.ReactionCodec
@@ -14,6 +16,50 @@ import org.xmtp.android.library.messages.walletAddress
1416
@RunWith(AndroidJUnit4::class)
1517
class ReactionTest {
1618

19+
@Test
20+
fun testCanDecodeLegacyForm() {
21+
val codec = ReactionCodec()
22+
23+
// This is how clients send reactions now.
24+
val canonicalEncoded = EncodedContent.newBuilder().also {
25+
it.type = ContentTypeReaction
26+
it.content = """
27+
{
28+
"action": "added",
29+
"content": "smile",
30+
"reference": "abc123",
31+
"schema": "shortcode"
32+
}
33+
""".trimIndent().toByteStringUtf8()
34+
}.build()
35+
36+
// Previously, some clients sent reactions like this.
37+
// So we test here to make sure we can still decode them.
38+
val legacyEncoded = EncodedContent.newBuilder().also {
39+
it.type = ContentTypeReaction
40+
it.putAllParameters(
41+
mapOf(
42+
"action" to "added",
43+
"reference" to "abc123",
44+
"schema" to "shortcode",
45+
)
46+
)
47+
it.content = "smile".toByteStringUtf8()
48+
}.build()
49+
50+
val canonical = codec.decode(canonicalEncoded)
51+
val legacy = codec.decode(legacyEncoded)
52+
53+
assertEquals(ReactionAction.added, canonical.action)
54+
assertEquals(ReactionAction.added, legacy.action)
55+
assertEquals("smile", canonical.content)
56+
assertEquals("smile", legacy.content)
57+
assertEquals("abc123", canonical.reference)
58+
assertEquals("abc123", legacy.reference)
59+
assertEquals(ReactionSchema.shortcode, canonical.schema)
60+
assertEquals(ReactionSchema.shortcode, legacy.schema)
61+
}
62+
1763
@Test
1864
fun testCanUseReactionCodec() {
1965
Client.register(codec = ReactionCodec())

library/src/main/java/org/xmtp/android/library/codecs/ReactionCodec.kt

+15-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,20 @@ data class ReactionCodec(override var contentType: ContentTypeId = ContentTypeRe
3737
}
3838

3939
override fun decode(content: EncodedContent): Reaction {
40-
val gson = GsonBuilder().create()
41-
return gson.fromJson(content.content.toStringUtf8(), Reaction::class.java)
40+
val text = content.content.toStringUtf8()
41+
42+
// First try to decode it in the canonical form.
43+
try {
44+
return GsonBuilder().create().fromJson(text, Reaction::class.java)
45+
} catch (ignore: Exception) {
46+
}
47+
48+
// If that fails, try to decode it in the legacy form.
49+
return Reaction(
50+
reference = content.parametersMap["reference"] ?: "",
51+
action = content.parametersMap["action"]?.let { ReactionAction.valueOf(it) }!!,
52+
schema = content.parametersMap["schema"]?.let { ReactionSchema.valueOf(it) }!!,
53+
content = text,
54+
)
4255
}
4356
}

0 commit comments

Comments
 (0)