Fetch, resize, reformat, and cache Atmosphere avatar images
atp.pics
atproto
1package fetch_test
2
3import (
4 "testing"
5
6 "atp.pics/internal/fetch"
7)
8
9func TestBuildParamStr(t *testing.T) {
10 tests := []struct {
11 w, h, q int
12 format string
13 wantParam string
14 wantExt string
15 }{
16 // No params → default.webp
17 {0, 0, 0, "webp", "", "webp"},
18 // Explicit ?f=webp&q=85 is identical output → same key as no params
19 {0, 0, 85, "webp", "", "webp"},
20
21 // Width only — implicit quality becomes explicit 85 in key
22 {200, 0, 0, "webp", "w200-q85", "webp"},
23 // Width only — explicit quality
24 {200, 0, 80, "webp", "w200-q80", "webp"},
25 // Height only — implicit quality
26 {0, 300, 0, "webp", "h300-q85", "webp"},
27 // Both dimensions, WebP, explicit quality
28 {200, 200, 85, "webp", "w200-h200-q85", "webp"},
29 // Both dimensions, JPEG, explicit quality
30 {200, 200, 80, "jpg", "w200-h200-q80", "jpg"},
31 // Both dimensions, JPEG, implicit quality
32 {200, 200, 0, "jpg", "w200-h200-q85", "jpg"},
33
34 // Format only, JPEG — uses f{fmt}-q{q} pattern
35 {0, 0, 0, "jpg", "fjpg-q85", "jpg"},
36 // Format only, JPEG, explicit quality
37 {0, 0, 75, "jpg", "fjpg-q75", "jpg"},
38
39 // PNG with resize — quality omitted from key
40 {100, 100, 90, "png", "w100-h100", "png"},
41 // PNG format only — uses f{fmt} pattern, no quality
42 {0, 0, 0, "png", "fpng", "png"},
43 }
44
45 for _, tt := range tests {
46 param, ext := fetch.BuildParamStr(tt.w, tt.h, tt.q, tt.format)
47 if param != tt.wantParam {
48 t.Errorf("BuildParamStr(%d,%d,%d,%q) param = %q, want %q",
49 tt.w, tt.h, tt.q, tt.format, param, tt.wantParam)
50 }
51 if ext != tt.wantExt {
52 t.Errorf("BuildParamStr(%d,%d,%d,%q) ext = %q, want %q",
53 tt.w, tt.h, tt.q, tt.format, ext, tt.wantExt)
54 }
55 }
56}
57
58func TestPublicURL(t *testing.T) {
59 const bucket = "my-bucket"
60 const key = "avatars/did:plc:abc/bafkrei123/default.webp"
61
62 t.Run("custom host", func(t *testing.T) {
63 store := fetch.New(nil, bucket, "cdn.example.com")
64 got := store.PublicURL(key)
65 want := "https://cdn.example.com/" + key
66 if got != want {
67 t.Errorf("PublicURL = %q, want %q", got, want)
68 }
69 })
70
71 t.Run("tigris fallback", func(t *testing.T) {
72 store := fetch.New(nil, bucket, "")
73 got := store.PublicURL(key)
74 want := "https://my-bucket.fly.storage.tigris.dev/" + key
75 if got != want {
76 t.Errorf("PublicURL = %q, want %q", got, want)
77 }
78 })
79}
80
81func TestTransformKey(t *testing.T) {
82 did := "did:plc:abc"
83 cid := "bafkrei123"
84
85 tests := []struct {
86 paramStr string
87 ext string
88 want string
89 }{
90 {"", "webp", "avatars/did:plc:abc/bafkrei123/default.webp"},
91 {"w200-h200-q85", "webp", "avatars/did:plc:abc/bafkrei123/w200-h200-q85.webp"},
92 {"w200-h200-q80", "jpg", "avatars/did:plc:abc/bafkrei123/w200-h200-q80.jpg"},
93 {"w100-h100", "png", "avatars/did:plc:abc/bafkrei123/w100-h100.png"},
94 }
95
96 for _, tt := range tests {
97 got := fetch.TransformKey(did, cid, tt.paramStr, tt.ext)
98 if got != tt.want {
99 t.Errorf("TransformKey(%q, %q) = %q, want %q", tt.paramStr, tt.ext, got, tt.want)
100 }
101 }
102}