A community based topic aggregation platform built on atproto
1package posts
2
3import (
4 "testing"
5
6 "github.com/stretchr/testify/assert"
7 "github.com/stretchr/testify/require"
8)
9
10func TestTransformBlobRefsToURLs(t *testing.T) {
11 t.Run("transforms external embed thumb from blob to URL", func(t *testing.T) {
12 post := &PostView{
13 Community: &CommunityRef{
14 DID: "did:plc:testcommunity",
15 PDSURL: "http://localhost:3001",
16 },
17 Embed: map[string]interface{}{
18 "$type": "social.coves.embed.external",
19 "external": map[string]interface{}{
20 "uri": "https://example.com",
21 "thumb": map[string]interface{}{
22 "$type": "blob",
23 "ref": map[string]interface{}{
24 "$link": "bafyreib6tbnql2ux3whnfysbzabthaj2vvck53nimhbi5g5a7jgvgr5eqm",
25 },
26 "mimeType": "image/jpeg",
27 "size": 52813,
28 },
29 },
30 },
31 }
32
33 TransformBlobRefsToURLs(post)
34
35 // Verify embed is still a map
36 embedMap, ok := post.Embed.(map[string]interface{})
37 require.True(t, ok, "embed should still be a map")
38
39 // Verify external is still a map
40 external, ok := embedMap["external"].(map[string]interface{})
41 require.True(t, ok, "external should be a map")
42
43 // Verify thumb is now a URL string
44 thumbURL, ok := external["thumb"].(string)
45 require.True(t, ok, "thumb should be a string URL")
46 assert.Equal(t,
47 "http://localhost:3001/xrpc/com.atproto.sync.getBlob?did=did:plc:testcommunity&cid=bafyreib6tbnql2ux3whnfysbzabthaj2vvck53nimhbi5g5a7jgvgr5eqm",
48 thumbURL)
49 })
50
51 t.Run("handles missing thumb gracefully", func(t *testing.T) {
52 post := &PostView{
53 Community: &CommunityRef{
54 DID: "did:plc:testcommunity",
55 PDSURL: "http://localhost:3001",
56 },
57 Embed: map[string]interface{}{
58 "$type": "social.coves.embed.external",
59 "external": map[string]interface{}{
60 "uri": "https://example.com",
61 // No thumb field
62 },
63 },
64 }
65
66 // Should not panic
67 TransformBlobRefsToURLs(post)
68
69 // Verify external is unchanged
70 embedMap := post.Embed.(map[string]interface{})
71 external := embedMap["external"].(map[string]interface{})
72 _, hasThumb := external["thumb"]
73 assert.False(t, hasThumb, "thumb should not be added")
74 })
75
76 t.Run("handles already-transformed URL thumb", func(t *testing.T) {
77 expectedURL := "http://localhost:3001/xrpc/com.atproto.sync.getBlob?did=did:plc:test&cid=bafytest"
78 post := &PostView{
79 Community: &CommunityRef{
80 DID: "did:plc:testcommunity",
81 PDSURL: "http://localhost:3001",
82 },
83 Embed: map[string]interface{}{
84 "$type": "social.coves.embed.external",
85 "external": map[string]interface{}{
86 "uri": "https://example.com",
87 "thumb": expectedURL, // Already a URL string
88 },
89 },
90 }
91
92 // Should not error or change the URL
93 TransformBlobRefsToURLs(post)
94
95 // Verify thumb is unchanged
96 embedMap := post.Embed.(map[string]interface{})
97 external := embedMap["external"].(map[string]interface{})
98 thumbURL, ok := external["thumb"].(string)
99 require.True(t, ok, "thumb should still be a string")
100 assert.Equal(t, expectedURL, thumbURL, "thumb URL should be unchanged")
101 })
102
103 t.Run("handles missing embed", func(t *testing.T) {
104 post := &PostView{
105 Community: &CommunityRef{
106 DID: "did:plc:testcommunity",
107 PDSURL: "http://localhost:3001",
108 },
109 Embed: nil,
110 }
111
112 // Should not panic
113 TransformBlobRefsToURLs(post)
114
115 // Verify embed is still nil
116 assert.Nil(t, post.Embed, "embed should remain nil")
117 })
118
119 t.Run("handles nil post", func(t *testing.T) {
120 // Should not panic
121 TransformBlobRefsToURLs(nil)
122 })
123
124 t.Run("handles missing community", func(t *testing.T) {
125 post := &PostView{
126 Community: nil,
127 Embed: map[string]interface{}{
128 "$type": "social.coves.embed.external",
129 "external": map[string]interface{}{
130 "uri": "https://example.com",
131 "thumb": map[string]interface{}{
132 "$type": "blob",
133 "ref": map[string]interface{}{
134 "$link": "bafyreib6tbnql2ux3whnfysbzabthaj2vvck53nimhbi5g5a7jgvgr5eqm",
135 },
136 },
137 },
138 },
139 }
140
141 // Should not panic or transform
142 TransformBlobRefsToURLs(post)
143
144 // Verify thumb is unchanged (still a blob)
145 embedMap := post.Embed.(map[string]interface{})
146 external := embedMap["external"].(map[string]interface{})
147 thumb, ok := external["thumb"].(map[string]interface{})
148 require.True(t, ok, "thumb should still be a map (blob ref)")
149 assert.Equal(t, "blob", thumb["$type"], "blob type should be unchanged")
150 })
151
152 t.Run("handles missing PDS URL", func(t *testing.T) {
153 post := &PostView{
154 Community: &CommunityRef{
155 DID: "did:plc:testcommunity",
156 PDSURL: "", // Empty PDS URL
157 },
158 Embed: map[string]interface{}{
159 "$type": "social.coves.embed.external",
160 "external": map[string]interface{}{
161 "uri": "https://example.com",
162 "thumb": map[string]interface{}{
163 "$type": "blob",
164 "ref": map[string]interface{}{
165 "$link": "bafyreib6tbnql2ux3whnfysbzabthaj2vvck53nimhbi5g5a7jgvgr5eqm",
166 },
167 },
168 },
169 },
170 }
171
172 // Should not panic or transform
173 TransformBlobRefsToURLs(post)
174
175 // Verify thumb is unchanged (still a blob)
176 embedMap := post.Embed.(map[string]interface{})
177 external := embedMap["external"].(map[string]interface{})
178 thumb, ok := external["thumb"].(map[string]interface{})
179 require.True(t, ok, "thumb should still be a map (blob ref)")
180 assert.Equal(t, "blob", thumb["$type"], "blob type should be unchanged")
181 })
182
183 t.Run("handles malformed blob ref gracefully", func(t *testing.T) {
184 post := &PostView{
185 Community: &CommunityRef{
186 DID: "did:plc:testcommunity",
187 PDSURL: "http://localhost:3001",
188 },
189 Embed: map[string]interface{}{
190 "$type": "social.coves.embed.external",
191 "external": map[string]interface{}{
192 "uri": "https://example.com",
193 "thumb": map[string]interface{}{
194 "$type": "blob",
195 "ref": "invalid-ref-format", // Should be a map with $link
196 },
197 },
198 },
199 }
200
201 // Should not panic
202 TransformBlobRefsToURLs(post)
203
204 // Verify thumb is unchanged (malformed blob)
205 embedMap := post.Embed.(map[string]interface{})
206 external := embedMap["external"].(map[string]interface{})
207 thumb, ok := external["thumb"].(map[string]interface{})
208 require.True(t, ok, "thumb should still be a map")
209 assert.Equal(t, "invalid-ref-format", thumb["ref"], "malformed ref should be unchanged")
210 })
211
212 t.Run("ignores non-external embed types", func(t *testing.T) {
213 post := &PostView{
214 Community: &CommunityRef{
215 DID: "did:plc:testcommunity",
216 PDSURL: "http://localhost:3001",
217 },
218 Embed: map[string]interface{}{
219 "$type": "social.coves.embed.images",
220 "images": []interface{}{
221 map[string]interface{}{
222 "image": map[string]interface{}{
223 "$type": "blob",
224 "ref": map[string]interface{}{
225 "$link": "bafyreib6tbnql2ux3whnfysbzabthaj2vvck53nimhbi5g5a7jgvgr5eqm",
226 },
227 },
228 },
229 },
230 },
231 }
232
233 // Should not transform non-external embeds
234 TransformBlobRefsToURLs(post)
235
236 // Verify images embed is unchanged
237 embedMap := post.Embed.(map[string]interface{})
238 images := embedMap["images"].([]interface{})
239 imageObj := images[0].(map[string]interface{})
240 imageBlob := imageObj["image"].(map[string]interface{})
241 assert.Equal(t, "blob", imageBlob["$type"], "image blob should be unchanged")
242 })
243}
244
245func TestTransformThumbToURL(t *testing.T) {
246 t.Run("transforms valid blob ref to URL", func(t *testing.T) {
247 external := map[string]interface{}{
248 "uri": "https://example.com",
249 "thumb": map[string]interface{}{
250 "$type": "blob",
251 "ref": map[string]interface{}{
252 "$link": "bafyreib6tbnql2ux3whnfysbzabthaj2vvck53nimhbi5g5a7jgvgr5eqm",
253 },
254 "mimeType": "image/jpeg",
255 "size": 52813,
256 },
257 }
258
259 transformThumbToURL(external, "did:plc:test", "http://localhost:3001")
260
261 thumbURL, ok := external["thumb"].(string)
262 require.True(t, ok, "thumb should be a string URL")
263 assert.Equal(t,
264 "http://localhost:3001/xrpc/com.atproto.sync.getBlob?did=did:plc:test&cid=bafyreib6tbnql2ux3whnfysbzabthaj2vvck53nimhbi5g5a7jgvgr5eqm",
265 thumbURL)
266 })
267
268 t.Run("does not transform if thumb is already string", func(t *testing.T) {
269 expectedURL := "http://localhost:3001/xrpc/com.atproto.sync.getBlob?did=did:plc:test&cid=bafytest"
270 external := map[string]interface{}{
271 "uri": "https://example.com",
272 "thumb": expectedURL,
273 }
274
275 transformThumbToURL(external, "did:plc:test", "http://localhost:3001")
276
277 thumbURL, ok := external["thumb"].(string)
278 require.True(t, ok, "thumb should still be a string")
279 assert.Equal(t, expectedURL, thumbURL, "thumb should be unchanged")
280 })
281
282 t.Run("does not transform if thumb is missing", func(t *testing.T) {
283 external := map[string]interface{}{
284 "uri": "https://example.com",
285 }
286
287 transformThumbToURL(external, "did:plc:test", "http://localhost:3001")
288
289 _, hasThumb := external["thumb"]
290 assert.False(t, hasThumb, "thumb should not be added")
291 })
292
293 t.Run("does not transform if CID is empty", func(t *testing.T) {
294 external := map[string]interface{}{
295 "uri": "https://example.com",
296 "thumb": map[string]interface{}{
297 "$type": "blob",
298 "ref": map[string]interface{}{
299 "$link": "", // Empty CID
300 },
301 },
302 }
303
304 transformThumbToURL(external, "did:plc:test", "http://localhost:3001")
305
306 // Verify thumb is unchanged
307 thumb, ok := external["thumb"].(map[string]interface{})
308 require.True(t, ok, "thumb should still be a map")
309 ref := thumb["ref"].(map[string]interface{})
310 assert.Equal(t, "", ref["$link"], "empty CID should be unchanged")
311 })
312}