A community based topic aggregation platform built on atproto
1package imageproxy
2
3import (
4 "errors"
5 "testing"
6 "time"
7)
8
9func TestConfig_Validate(t *testing.T) {
10 tests := []struct {
11 name string
12 config Config
13 wantErr error
14 }{
15 {
16 name: "valid default config",
17 config: DefaultConfig(),
18 wantErr: nil,
19 },
20 {
21 name: "valid enabled config",
22 config: Config{
23 Enabled: true,
24 BaseURL: "/img",
25 CachePath: "/var/cache/images",
26 CacheMaxGB: 10,
27 FetchTimeout: 30 * time.Second,
28 MaxSourceSizeMB: 10,
29 },
30 wantErr: nil,
31 },
32 {
33 name: "invalid CacheMaxGB zero",
34 config: Config{
35 Enabled: false,
36 BaseURL: "/img",
37 CachePath: "/var/cache/images",
38 CacheMaxGB: 0,
39 FetchTimeout: 30 * time.Second,
40 MaxSourceSizeMB: 10,
41 },
42 wantErr: ErrInvalidCacheMaxGB,
43 },
44 {
45 name: "invalid CacheMaxGB negative",
46 config: Config{
47 Enabled: false,
48 BaseURL: "/img",
49 CachePath: "/var/cache/images",
50 CacheMaxGB: -5,
51 FetchTimeout: 30 * time.Second,
52 MaxSourceSizeMB: 10,
53 },
54 wantErr: ErrInvalidCacheMaxGB,
55 },
56 {
57 name: "invalid FetchTimeout zero",
58 config: Config{
59 Enabled: false,
60 BaseURL: "/img",
61 CachePath: "/var/cache/images",
62 CacheMaxGB: 10,
63 FetchTimeout: 0,
64 MaxSourceSizeMB: 10,
65 },
66 wantErr: ErrInvalidFetchTimeout,
67 },
68 {
69 name: "invalid FetchTimeout negative",
70 config: Config{
71 Enabled: false,
72 BaseURL: "/img",
73 CachePath: "/var/cache/images",
74 CacheMaxGB: 10,
75 FetchTimeout: -1 * time.Second,
76 MaxSourceSizeMB: 10,
77 },
78 wantErr: ErrInvalidFetchTimeout,
79 },
80 {
81 name: "invalid MaxSourceSizeMB zero",
82 config: Config{
83 Enabled: false,
84 BaseURL: "/img",
85 CachePath: "/var/cache/images",
86 CacheMaxGB: 10,
87 FetchTimeout: 30 * time.Second,
88 MaxSourceSizeMB: 0,
89 },
90 wantErr: ErrInvalidMaxSourceSize,
91 },
92 {
93 name: "invalid MaxSourceSizeMB negative",
94 config: Config{
95 Enabled: false,
96 BaseURL: "/img",
97 CachePath: "/var/cache/images",
98 CacheMaxGB: 10,
99 FetchTimeout: 30 * time.Second,
100 MaxSourceSizeMB: -5,
101 },
102 wantErr: ErrInvalidMaxSourceSize,
103 },
104 {
105 name: "enabled but missing CachePath",
106 config: Config{
107 Enabled: true,
108 BaseURL: "/img",
109 CachePath: "",
110 CacheMaxGB: 10,
111 FetchTimeout: 30 * time.Second,
112 MaxSourceSizeMB: 10,
113 },
114 wantErr: ErrMissingCachePath,
115 },
116 {
117 name: "enabled allows empty BaseURL for relative URLs",
118 config: Config{
119 Enabled: true,
120 BaseURL: "",
121 CachePath: "/var/cache/images",
122 CacheMaxGB: 10,
123 FetchTimeout: 30 * time.Second,
124 MaxSourceSizeMB: 10,
125 },
126 wantErr: nil,
127 },
128 {
129 name: "disabled allows empty CachePath",
130 config: Config{
131 Enabled: false,
132 BaseURL: "/img",
133 CachePath: "",
134 CacheMaxGB: 10,
135 FetchTimeout: 30 * time.Second,
136 MaxSourceSizeMB: 10,
137 },
138 wantErr: nil,
139 },
140 {
141 name: "disabled allows empty BaseURL",
142 config: Config{
143 Enabled: false,
144 BaseURL: "",
145 CachePath: "/var/cache/images",
146 CacheMaxGB: 10,
147 FetchTimeout: 30 * time.Second,
148 MaxSourceSizeMB: 10,
149 },
150 wantErr: nil,
151 },
152 {
153 name: "valid TTL zero (disabled)",
154 config: Config{
155 Enabled: true,
156 BaseURL: "",
157 CachePath: "/var/cache/images",
158 CacheMaxGB: 10,
159 CacheTTLDays: 0,
160 FetchTimeout: 30 * time.Second,
161 MaxSourceSizeMB: 10,
162 },
163 wantErr: nil,
164 },
165 {
166 name: "valid TTL positive",
167 config: Config{
168 Enabled: true,
169 BaseURL: "",
170 CachePath: "/var/cache/images",
171 CacheMaxGB: 10,
172 CacheTTLDays: 30,
173 FetchTimeout: 30 * time.Second,
174 MaxSourceSizeMB: 10,
175 },
176 wantErr: nil,
177 },
178 {
179 name: "invalid TTL negative",
180 config: Config{
181 Enabled: true,
182 BaseURL: "",
183 CachePath: "/var/cache/images",
184 CacheMaxGB: 10,
185 CacheTTLDays: -1,
186 FetchTimeout: 30 * time.Second,
187 MaxSourceSizeMB: 10,
188 },
189 wantErr: ErrInvalidCacheTTL,
190 },
191 }
192
193 for _, tt := range tests {
194 t.Run(tt.name, func(t *testing.T) {
195 err := tt.config.Validate()
196 if tt.wantErr == nil {
197 if err != nil {
198 t.Errorf("expected no error, got: %v", err)
199 }
200 } else {
201 if !errors.Is(err, tt.wantErr) {
202 t.Errorf("expected %v, got: %v", tt.wantErr, err)
203 }
204 }
205 })
206 }
207}
208
209func TestDefaultConfig(t *testing.T) {
210 cfg := DefaultConfig()
211
212 // Verify default values
213 if !cfg.Enabled {
214 t.Error("expected Enabled to be true by default")
215 }
216 if cfg.BaseURL != "" {
217 t.Errorf("expected empty BaseURL for relative URLs, got %q", cfg.BaseURL)
218 }
219 if cfg.CachePath != "/var/cache/coves/images" {
220 t.Errorf("expected CachePath '/var/cache/coves/images', got %q", cfg.CachePath)
221 }
222 if cfg.CacheMaxGB != 10 {
223 t.Errorf("expected CacheMaxGB 10, got %d", cfg.CacheMaxGB)
224 }
225 if cfg.CacheTTLDays != 30 {
226 t.Errorf("expected CacheTTLDays 30, got %d", cfg.CacheTTLDays)
227 }
228 if cfg.CleanupInterval != 1*time.Hour {
229 t.Errorf("expected CleanupInterval 1h, got %v", cfg.CleanupInterval)
230 }
231 if cfg.CDNURL != "" {
232 t.Errorf("expected empty CDNURL, got %q", cfg.CDNURL)
233 }
234 if cfg.FetchTimeout != 30*time.Second {
235 t.Errorf("expected FetchTimeout 30s, got %v", cfg.FetchTimeout)
236 }
237 if cfg.MaxSourceSizeMB != 10 {
238 t.Errorf("expected MaxSourceSizeMB 10, got %d", cfg.MaxSourceSizeMB)
239 }
240
241 // Default config should be valid
242 if err := cfg.Validate(); err != nil {
243 t.Errorf("default config should be valid, got error: %v", err)
244 }
245}