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}