this repo has no description
1import Testing
2import Foundation
3@testable import EffemKit
4
5@Suite("PodcastRef")
6struct PodcastRefTests {
7 @Test func decodesFromJSON() throws {
8 let json = """
9 {"feedId": 75075, "feedUrl": "https://example.com/feed.xml", "podcastGuid": "917393e3-1b1e-5cef-ace4-edaa54e1f810"}
10 """.data(using: .utf8)!
11
12 let ref = try JSONDecoder().decode(PodcastRef.self, from: json)
13 #expect(ref.feedId == 75075)
14 #expect(ref.feedUrl == "https://example.com/feed.xml")
15 #expect(ref.podcastGuid == "917393e3-1b1e-5cef-ace4-edaa54e1f810")
16 }
17
18 @Test func decodesWithMinimalFields() throws {
19 let json = """
20 {"feedId": 42}
21 """.data(using: .utf8)!
22
23 let ref = try JSONDecoder().decode(PodcastRef.self, from: json)
24 #expect(ref.feedId == 42)
25 #expect(ref.feedUrl == nil)
26 #expect(ref.podcastGuid == nil)
27 }
28
29 @Test func roundTrips() throws {
30 let ref = PodcastRef(feedId: 100, feedUrl: "https://example.com/rss", podcastGuid: "abc-123")
31 let data = try JSONEncoder().encode(ref)
32 let decoded = try JSONDecoder().decode(PodcastRef.self, from: data)
33 #expect(ref == decoded)
34 }
35
36 @Test func toRecordIncludesOnlyNonNilFields() {
37 let minimal = PodcastRef(feedId: 1)
38 let record = minimal.toRecord()
39 #expect(record["feedId"] as? Int == 1)
40 #expect(record["feedUrl"] == nil)
41 #expect(record["podcastGuid"] == nil)
42
43 let full = PodcastRef(feedId: 2, feedUrl: "https://x.com/rss", podcastGuid: "guid")
44 let fullRecord = full.toRecord()
45 #expect(fullRecord["feedId"] as? Int == 2)
46 #expect(fullRecord["feedUrl"] as? String == "https://x.com/rss")
47 #expect(fullRecord["podcastGuid"] as? String == "guid")
48 }
49}
50
51@Suite("EpisodeRef")
52struct EpisodeRefTests {
53 @Test func decodesFromJSON() throws {
54 let json = """
55 {"feedId": 75075, "episodeId": 1721351091, "episodeGuid": "ac34129c", "podcastGuid": "917393e3"}
56 """.data(using: .utf8)!
57
58 let ref = try JSONDecoder().decode(EpisodeRef.self, from: json)
59 #expect(ref.feedId == 75075)
60 #expect(ref.episodeId == 1721351091)
61 #expect(ref.episodeGuid == "ac34129c")
62 #expect(ref.podcastGuid == "917393e3")
63 }
64
65 @Test func decodesWithMinimalFields() throws {
66 let json = """
67 {"feedId": 10, "episodeId": 20}
68 """.data(using: .utf8)!
69
70 let ref = try JSONDecoder().decode(EpisodeRef.self, from: json)
71 #expect(ref.feedId == 10)
72 #expect(ref.episodeId == 20)
73 #expect(ref.episodeGuid == nil)
74 }
75
76 @Test func roundTrips() throws {
77 let ref = EpisodeRef(feedId: 5, episodeId: 10, episodeGuid: "ep-guid")
78 let data = try JSONEncoder().encode(ref)
79 let decoded = try JSONDecoder().decode(EpisodeRef.self, from: data)
80 #expect(ref == decoded)
81 }
82
83 @Test func toRecordIncludesOnlyNonNilFields() {
84 let minimal = EpisodeRef(feedId: 1, episodeId: 2)
85 let record = minimal.toRecord()
86 #expect(record["feedId"] as? Int == 1)
87 #expect(record["episodeId"] as? Int == 2)
88 #expect(record["episodeGuid"] == nil)
89 }
90}
91
92@Suite("Comment")
93struct CommentTests {
94 @Test func decodesFromJSON() throws {
95 let json = """
96 {
97 "did": "did:plc:abc123",
98 "rkey": "3jm2szx5c47mo",
99 "episode": {"feedId": 75075, "episodeId": 100},
100 "text": "Great episode!",
101 "timestamp": 120,
102 "createdAt": "2026-01-15T10:30:00Z",
103 "author": {
104 "did": "did:plc:abc123",
105 "handle": "alice.bsky.social",
106 "displayName": "Alice"
107 }
108 }
109 """.data(using: .utf8)!
110
111 let comment = try JSONDecoder().decode(EffemKit.Comment.self, from: json)
112 #expect(comment.did == "did:plc:abc123")
113 #expect(comment.text == "Great episode!")
114 #expect(comment.timestamp == 120)
115 #expect(comment.episode.feedId == 75075)
116 #expect(comment.author?.displayName == "Alice")
117 #expect(comment.uri == "at://did:plc:abc123/xyz.effem.feed.comment/3jm2szx5c47mo")
118 }
119}
120
121@Suite("Subscription")
122struct SubscriptionTests {
123 @Test func uriIsCorrect() throws {
124 let json = """
125 {
126 "did": "did:plc:xyz",
127 "rkey": "abc123",
128 "podcast": {"feedId": 42},
129 "createdAt": "2026-01-01T00:00:00Z"
130 }
131 """.data(using: .utf8)!
132
133 let sub = try JSONDecoder().decode(Subscription.self, from: json)
134 #expect(sub.uri == "at://did:plc:xyz/xyz.effem.feed.subscription/abc123")
135 #expect(sub.id == "did:plc:xyz/abc123")
136 }
137}
138
139@Suite("SocialOverlay")
140struct SocialOverlayTests {
141 @Test func decodesPartialFields() throws {
142 let json = """
143 {"subscriberCount": 42, "commentCount": 10}
144 """.data(using: .utf8)!
145
146 let overlay = try JSONDecoder().decode(SocialOverlay.self, from: json)
147 #expect(overlay.subscriberCount == 42)
148 #expect(overlay.commentCount == 10)
149 #expect(overlay.recommendationCount == nil)
150 #expect(overlay.bookmarkCount == nil)
151 #expect(overlay.subscribedByFollowing == nil)
152 }
153
154 @Test func decodesFullFields() throws {
155 let json = """
156 {
157 "subscriberCount": 100,
158 "commentCount": 50,
159 "recommendationCount": 25,
160 "bookmarkCount": 10,
161 "subscribedByFollowing": ["did:plc:a", "did:plc:b"]
162 }
163 """.data(using: .utf8)!
164
165 let overlay = try JSONDecoder().decode(SocialOverlay.self, from: json)
166 #expect(overlay.subscriberCount == 100)
167 #expect(overlay.subscribedByFollowing?.count == 2)
168 }
169}
170
171@Suite("Bookmark")
172struct BookmarkTests {
173 @Test func decodesFromJSON() throws {
174 let json = """
175 {
176 "did": "did:plc:xyz",
177 "rkey": "tid123",
178 "episode": {"feedId": 1, "episodeId": 2},
179 "timestamp": 300,
180 "createdAt": "2026-02-01T00:00:00Z"
181 }
182 """.data(using: .utf8)!
183
184 let bookmark = try JSONDecoder().decode(Bookmark.self, from: json)
185 #expect(bookmark.timestamp == 300)
186 #expect(bookmark.uri == "at://did:plc:xyz/xyz.effem.feed.bookmark/tid123")
187 }
188}
189
190@Suite("PodcastList")
191struct PodcastListTests {
192 @Test func decodesFromJSON() throws {
193 let json = """
194 {
195 "did": "did:plc:xyz",
196 "rkey": "list1",
197 "name": "My Favorite Pods",
198 "description": "The best ones",
199 "podcasts": [{"feedId": 1}, {"feedId": 2, "feedUrl": "https://example.com/rss"}],
200 "createdAt": "2026-01-01T00:00:00Z"
201 }
202 """.data(using: .utf8)!
203
204 let list = try JSONDecoder().decode(PodcastList.self, from: json)
205 #expect(list.name == "My Favorite Pods")
206 #expect(list.podcasts.count == 2)
207 #expect(list.podcasts[1].feedUrl == "https://example.com/rss")
208 }
209}
210
211@Suite("CommentReplyRef")
212struct CommentReplyRefTests {
213 @Test func initializesCorrectly() {
214 let ref = CommentReplyRef(
215 rootURI: "at://did:plc:a/xyz.effem.feed.comment/root",
216 rootCID: "bafyreia",
217 parentURI: "at://did:plc:b/xyz.effem.feed.comment/parent",
218 parentCID: "bafyreib"
219 )
220 #expect(ref.rootURI.contains("root"))
221 #expect(ref.parentCID == "bafyreib")
222 }
223}