Skip to content

Commit

Permalink
fix: the reaction codec crash
Browse files Browse the repository at this point in the history
  • Loading branch information
nplasterer committed Sep 13, 2023
1 parent 45276cb commit 77db9c5
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 7 deletions.
38 changes: 31 additions & 7 deletions Sources/XMTP/Codecs/ReactionCodec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,35 @@ public struct Reaction: Codable {
}

public enum ReactionAction: String, Codable {
case added, removed
case added, removed, unknown

public init(rawValue: String) {
switch rawValue {
case "added":
self = .added
case "removed":
self = .removed
default:
self = .unknown
}
}
}

public enum ReactionSchema: String, Codable {
case unicode, shortcode, custom
case unicode, shortcode, custom, unknown

public init(rawValue: String) {
switch rawValue {
case "unicode":
self = .unicode
case "shortcode":
self = .shortcode
case "custom":
self = .custom
default:
self = .unknown
}
}
}

public struct ReactionCodec: ContentCodec {
Expand All @@ -55,22 +79,22 @@ public struct ReactionCodec: ContentCodec {
}
// swiftlint:disable no_optional_try
// If that fails, try to decode it in the legacy form.
// swiftlint:disable force_unwrapping
return Reaction(
reference: content.parameters["reference"] ?? "",
action: ReactionAction(rawValue: content.parameters["action"] ?? "")!,
action: ReactionAction(rawValue: content.parameters["action"] ?? ""),
content: String(data: content.content, encoding: .utf8) ?? "",
schema: ReactionSchema(rawValue: content.parameters["schema"] ?? "")!
schema: ReactionSchema(rawValue: content.parameters["schema"] ?? "")
)
//swiftlint:disable force_unwrapping
}

public func fallback(content: Reaction) throws -> String? {
switch content.action {
case .added:
return "Reacted “\(content.content)” to an earlier message"
case .removed:
return "Removed “\(content.content)” from an earlier message"
return "Removed “\(content.content)” from an earlier message"
case .unknown:
return nil
}
}
}
41 changes: 41 additions & 0 deletions Tests/XMTPTests/ReactionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,45 @@ class ReactionTests: XCTestCase {
XCTAssertEqual(ReactionAction.added, content.action)
XCTAssertEqual(ReactionSchema.unicode, content.schema)
}

func testCanDecodeEmptyForm() async throws {
let codec = ReactionCodec()

// This is how clients send reactions now.
let canonicalEncoded = EncodedContent.with {
$0.type = ContentTypeReaction
$0.content = Data("""
{
"action": "",
"content": "smile",
"reference": "",
"schema": ""
}
""".utf8)
}

// Previously, some clients sent reactions like this.
// So we test here to make sure we can still decode them.
let legacyEncoded = EncodedContent.with {
$0.type = ContentTypeReaction
$0.parameters = [
"action": "",
"reference": "",
"schema": "",
]
$0.content = Data("smile".utf8)
}

let canonical = try codec.decode(content: canonicalEncoded)
let legacy = try codec.decode(content: legacyEncoded)

XCTAssertEqual(ReactionAction.unknown, canonical.action)
XCTAssertEqual(ReactionAction.unknown, legacy.action)
XCTAssertEqual("smile", canonical.content)
XCTAssertEqual("smile", legacy.content)
XCTAssertEqual("", canonical.reference)
XCTAssertEqual("", legacy.reference)
XCTAssertEqual(ReactionSchema.unknown, canonical.schema)
XCTAssertEqual(ReactionSchema.unknown, legacy.schema)
}
}

0 comments on commit 77db9c5

Please sign in to comment.