Skip to content

Commit

Permalink
fix: normalize reaction encoding, support legacy form (#112)
Browse files Browse the repository at this point in the history
* fix: normalize reaction encoding, support legacy form

* fix linter issues

---------

Co-authored-by: Naomi Plasterer <[email protected]>
  • Loading branch information
dmccartney and nplasterer authored Sep 5, 2023
1 parent 3ec0620 commit b82ac6c
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package org.xmtp.android.library

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.protobuf.kotlin.toByteStringUtf8
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.xmtp.android.library.codecs.ContentTypeReaction
import org.xmtp.android.library.codecs.EncodedContent
import org.xmtp.android.library.codecs.Reaction
import org.xmtp.android.library.codecs.ReactionAction
import org.xmtp.android.library.codecs.ReactionCodec
Expand All @@ -14,6 +16,50 @@ import org.xmtp.android.library.messages.walletAddress
@RunWith(AndroidJUnit4::class)
class ReactionTest {

@Test
fun testCanDecodeLegacyForm() {
val codec = ReactionCodec()

// This is how clients send reactions now.
val canonicalEncoded = EncodedContent.newBuilder().also {
it.type = ContentTypeReaction
it.content = """
{
"action": "added",
"content": "smile",
"reference": "abc123",
"schema": "shortcode"
}
""".trimIndent().toByteStringUtf8()
}.build()

// Previously, some clients sent reactions like this.
// So we test here to make sure we can still decode them.
val legacyEncoded = EncodedContent.newBuilder().also {
it.type = ContentTypeReaction
it.putAllParameters(
mapOf(
"action" to "added",
"reference" to "abc123",
"schema" to "shortcode",
)
)
it.content = "smile".toByteStringUtf8()
}.build()

val canonical = codec.decode(canonicalEncoded)
val legacy = codec.decode(legacyEncoded)

assertEquals(ReactionAction.added, canonical.action)
assertEquals(ReactionAction.added, legacy.action)
assertEquals("smile", canonical.content)
assertEquals("smile", legacy.content)
assertEquals("abc123", canonical.reference)
assertEquals("abc123", legacy.reference)
assertEquals(ReactionSchema.shortcode, canonical.schema)
assertEquals(ReactionSchema.shortcode, legacy.schema)
}

@Test
fun testCanUseReactionCodec() {
Client.register(codec = ReactionCodec())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,20 @@ data class ReactionCodec(override var contentType: ContentTypeId = ContentTypeRe
}

override fun decode(content: EncodedContent): Reaction {
val gson = GsonBuilder().create()
return gson.fromJson(content.content.toStringUtf8(), Reaction::class.java)
val text = content.content.toStringUtf8()

// First try to decode it in the canonical form.
try {
return GsonBuilder().create().fromJson(text, Reaction::class.java)
} catch (ignore: Exception) {
}

// If that fails, try to decode it in the legacy form.
return Reaction(
reference = content.parametersMap["reference"] ?: "",
action = content.parametersMap["action"]?.let { ReactionAction.valueOf(it) }!!,
schema = content.parametersMap["schema"]?.let { ReactionSchema.valueOf(it) }!!,
content = text,
)
}
}

0 comments on commit b82ac6c

Please sign in to comment.