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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
@testable import Grain
import XCTest
final class FacetCodingTests: GrainTestCase {
private let decoder = JSONDecoder()
private let encoder = JSONEncoder()
// MARK: - Decoding
func testDecodeMention() throws {
let json = Data("""
{"$type": "app.bsky.richtext.facet#mention", "did": "did:plc:abc123"}
""".utf8)
let feature = try decoder.decode(FacetFeature.self, from: json)
if case let .mention(did) = feature {
XCTAssertEqual(did, "did:plc:abc123")
} else {
XCTFail("Expected mention, got \(feature)")
}
}
func testDecodeLink() throws {
let json = Data("""
{"$type": "app.bsky.richtext.facet#link", "uri": "https://example.com"}
""".utf8)
let feature = try decoder.decode(FacetFeature.self, from: json)
if case let .link(uri) = feature {
XCTAssertEqual(uri, "https://example.com")
} else {
XCTFail("Expected link, got \(feature)")
}
}
func testDecodeTag() throws {
let json = Data("""
{"$type": "app.bsky.richtext.facet#tag", "tag": "photography"}
""".utf8)
let feature = try decoder.decode(FacetFeature.self, from: json)
if case let .tag(tag) = feature {
XCTAssertEqual(tag, "photography")
} else {
XCTFail("Expected tag, got \(feature)")
}
}
func testDecodeUnknownTypeThrows() {
let json = Data("""
{"$type": "app.bsky.richtext.facet#unknown", "data": "stuff"}
""".utf8)
XCTAssertThrowsError(try decoder.decode(FacetFeature.self, from: json))
}
// MARK: - Encoding round-trips
func testMentionRoundTrip() throws {
let original = FacetFeature.mention(did: "did:plc:xyz")
let data = try encoder.encode(original)
let decoded = try decoder.decode(FacetFeature.self, from: data)
if case let .mention(did) = decoded {
XCTAssertEqual(did, "did:plc:xyz")
} else {
XCTFail("Round-trip failed")
}
}
func testLinkRoundTrip() throws {
let original = FacetFeature.link(uri: "https://grain.social")
let data = try encoder.encode(original)
let decoded = try decoder.decode(FacetFeature.self, from: data)
if case let .link(uri) = decoded {
XCTAssertEqual(uri, "https://grain.social")
} else {
XCTFail("Round-trip failed")
}
}
func testTagRoundTrip() throws {
let original = FacetFeature.tag(tag: "streetphoto")
let data = try encoder.encode(original)
let decoded = try decoder.decode(FacetFeature.self, from: data)
if case let .tag(tag) = decoded {
XCTAssertEqual(tag, "streetphoto")
} else {
XCTFail("Round-trip failed")
}
}
// MARK: - Full Facet
func testDecodeFacetWithFeatures() throws {
let json = Data("""
{
"index": {"byteStart": 0, "byteEnd": 10},
"features": [
{"$type": "app.bsky.richtext.facet#mention", "did": "did:plc:test"}
]
}
""".utf8)
let facet = try decoder.decode(Facet.self, from: json)
XCTAssertEqual(facet.index.byteStart, 0)
XCTAssertEqual(facet.index.byteEnd, 10)
XCTAssertEqual(facet.features.count, 1)
}
}