|
190 | 190 |
|
191 | 191 | (deftest parse-dynamic-string-test |
192 | 192 | (testing "returns nil for nil input" |
193 | | - (is (nil? (#'config/parse-dynamic-string nil "/tmp")))) |
| 193 | + (is (nil? (#'config/parse-dynamic-string nil "/tmp" {})))) |
194 | 194 |
|
195 | 195 | (testing "returns string unchanged when no patterns" |
196 | | - (is (= "hello world" (#'config/parse-dynamic-string "hello world" "/tmp")))) |
| 196 | + (is (= "hello world" (#'config/parse-dynamic-string "hello world" "/tmp" {})))) |
197 | 197 |
|
198 | 198 | (testing "replaces environment variable patterns" |
199 | 199 | (with-redefs [config/get-env (fn [env-var] |
200 | 200 | (case env-var |
201 | 201 | "TEST_VAR" "test-value" |
202 | 202 | "ANOTHER_VAR" "another-value" |
203 | 203 | nil))] |
204 | | - (is (= "test-value" (#'config/parse-dynamic-string "${env:TEST_VAR}" "/tmp"))) |
205 | | - (is (= "prefix test-value suffix" (#'config/parse-dynamic-string "prefix ${env:TEST_VAR} suffix" "/tmp"))) |
206 | | - (is (= "test-value and another-value" (#'config/parse-dynamic-string "${env:TEST_VAR} and ${env:ANOTHER_VAR}" "/tmp"))))) |
| 204 | + (is (= "test-value" (#'config/parse-dynamic-string "${env:TEST_VAR}" "/tmp" {}))) |
| 205 | + (is (= "prefix test-value suffix" (#'config/parse-dynamic-string "prefix ${env:TEST_VAR} suffix" "/tmp" {}))) |
| 206 | + (is (= "test-value and another-value" (#'config/parse-dynamic-string "${env:TEST_VAR} and ${env:ANOTHER_VAR}" "/tmp" {}))))) |
207 | 207 |
|
208 | 208 | (testing "replaces undefined env var with empty string" |
209 | 209 | (with-redefs [config/get-env (constantly nil)] |
210 | | - (is (= "" (#'config/parse-dynamic-string "${env:UNDEFINED_VAR}" "/tmp"))) |
211 | | - (is (= "prefix suffix" (#'config/parse-dynamic-string "prefix ${env:UNDEFINED_VAR} suffix" "/tmp"))))) |
| 210 | + (is (= "" (#'config/parse-dynamic-string "${env:UNDEFINED_VAR}" "/tmp" {}))) |
| 211 | + (is (= "prefix suffix" (#'config/parse-dynamic-string "prefix ${env:UNDEFINED_VAR} suffix" "/tmp" {}))))) |
212 | 212 |
|
213 | 213 | (testing "replaces undefined env var with default value" |
214 | 214 | (with-redefs [config/get-env (constantly nil)] |
215 | | - (is (= "default-value" (#'config/parse-dynamic-string "${env:UNDEFINED_VAR:default-value}" "/tmp"))) |
216 | | - (is (= "http://localhost:11434" (#'config/parse-dynamic-string "${env:OLLAMA_API_URL:http://localhost:11434}" "/tmp"))) |
217 | | - (is (= "prefix default-value suffix" (#'config/parse-dynamic-string "prefix ${env:UNDEFINED_VAR:default-value} suffix" "/tmp"))))) |
| 215 | + (is (= "default-value" (#'config/parse-dynamic-string "${env:UNDEFINED_VAR:default-value}" "/tmp" {}))) |
| 216 | + (is (= "http://localhost:11434" (#'config/parse-dynamic-string "${env:OLLAMA_API_URL:http://localhost:11434}" "/tmp" {}))) |
| 217 | + (is (= "prefix default-value suffix" (#'config/parse-dynamic-string "prefix ${env:UNDEFINED_VAR:default-value} suffix" "/tmp" {}))))) |
218 | 218 |
|
219 | 219 | (testing "uses env var value when set, ignoring default" |
220 | 220 | (with-redefs [config/get-env (fn [env-var] |
221 | 221 | (case env-var |
222 | 222 | "TEST_VAR" "actual-value" |
223 | 223 | "OLLAMA_API_URL" "http://custom:8080" |
224 | 224 | nil))] |
225 | | - (is (= "actual-value" (#'config/parse-dynamic-string "${env:TEST_VAR:default-value}" "/tmp"))) |
226 | | - (is (= "http://custom:8080" (#'config/parse-dynamic-string "${env:OLLAMA_API_URL:http://localhost:11434}" "/tmp"))))) |
| 225 | + (is (= "actual-value" (#'config/parse-dynamic-string "${env:TEST_VAR:default-value}" "/tmp" {}))) |
| 226 | + (is (= "http://custom:8080" (#'config/parse-dynamic-string "${env:OLLAMA_API_URL:http://localhost:11434}" "/tmp" {}))))) |
227 | 227 |
|
228 | 228 | (testing "handles default values with special characters" |
229 | 229 | (with-redefs [config/get-env (constantly nil)] |
230 | | - (is (= "http://localhost:11434/api" (#'config/parse-dynamic-string "${env:API_URL:http://localhost:11434/api}" "/tmp"))) |
231 | | - (is (= "value-with-dashes" (#'config/parse-dynamic-string "${env:VAR:value-with-dashes}" "/tmp"))) |
232 | | - (is (= "value_with_underscores" (#'config/parse-dynamic-string "${env:VAR:value_with_underscores}" "/tmp"))) |
233 | | - (is (= "/path/to/file" (#'config/parse-dynamic-string "${env:VAR:/path/to/file}" "/tmp"))))) |
| 230 | + (is (= "http://localhost:11434/api" (#'config/parse-dynamic-string "${env:API_URL:http://localhost:11434/api}" "/tmp" {}))) |
| 231 | + (is (= "value-with-dashes" (#'config/parse-dynamic-string "${env:VAR:value-with-dashes}" "/tmp" {}))) |
| 232 | + (is (= "value_with_underscores" (#'config/parse-dynamic-string "${env:VAR:value_with_underscores}" "/tmp" {}))) |
| 233 | + (is (= "/path/to/file" (#'config/parse-dynamic-string "${env:VAR:/path/to/file}" "/tmp" {}))))) |
234 | 234 |
|
235 | 235 | (testing "handles empty default value" |
236 | 236 | (with-redefs [config/get-env (constantly nil)] |
237 | | - (is (= "" (#'config/parse-dynamic-string "${env:UNDEFINED_VAR:}" "/tmp"))) |
238 | | - (is (= "prefix suffix" (#'config/parse-dynamic-string "prefix ${env:UNDEFINED_VAR:} suffix" "/tmp"))))) |
| 237 | + (is (= "" (#'config/parse-dynamic-string "${env:UNDEFINED_VAR:}" "/tmp" {}))) |
| 238 | + (is (= "prefix suffix" (#'config/parse-dynamic-string "prefix ${env:UNDEFINED_VAR:} suffix" "/tmp" {}))))) |
239 | 239 |
|
240 | 240 | (testing "handles multiple env vars with mixed default values" |
241 | 241 | (with-redefs [config/get-env (fn [env-var] |
242 | 242 | (case env-var |
243 | 243 | "DEFINED_VAR" "defined" |
244 | 244 | nil))] |
245 | 245 | (is (= "defined and default-value" |
246 | | - (#'config/parse-dynamic-string "${env:DEFINED_VAR:fallback1} and ${env:UNDEFINED_VAR:default-value}" "/tmp"))) |
| 246 | + (#'config/parse-dynamic-string "${env:DEFINED_VAR:fallback1} and ${env:UNDEFINED_VAR:default-value}" "/tmp" {}))) |
247 | 247 | (is (= "defined and " |
248 | | - (#'config/parse-dynamic-string "${env:DEFINED_VAR} and ${env:UNDEFINED_VAR}" "/tmp"))))) |
| 248 | + (#'config/parse-dynamic-string "${env:DEFINED_VAR} and ${env:UNDEFINED_VAR}" "/tmp" {}))))) |
249 | 249 |
|
250 | 250 | (testing "replaces file pattern with file content - absolute path" |
251 | 251 | (with-redefs [fs/absolute? (fn [path] (= path "/absolute/file.txt")) |
252 | 252 | slurp (fn [path] |
253 | 253 | (if (= (str path) "/absolute/file.txt") |
254 | 254 | "test file content" |
255 | 255 | (throw (ex-info "File not found" {}))))] |
256 | | - (is (= "test file content" (#'config/parse-dynamic-string "${file:/absolute/file.txt}" "/tmp"))))) |
| 256 | + (is (= "test file content" (#'config/parse-dynamic-string "${file:/absolute/file.txt}" "/tmp" {}))))) |
257 | 257 |
|
258 | 258 | (testing "replaces file pattern with file content - relative path" |
259 | 259 | (with-redefs [fs/absolute? (fn [_] false) |
|
262 | 262 | (if (= path "/tmp/test.txt") |
263 | 263 | "relative file content" |
264 | 264 | (throw (ex-info "File not found" {}))))] |
265 | | - (is (= "relative file content" (#'config/parse-dynamic-string "${file:test.txt}" "/tmp"))))) |
| 265 | + (is (= "relative file content" (#'config/parse-dynamic-string "${file:test.txt}" "/tmp" {}))))) |
266 | 266 |
|
267 | 267 | (testing "replaces file pattern with empty string when file not found" |
268 | 268 | (with-redefs [logger/warn (fn [& _] nil) |
269 | 269 | fs/absolute? (fn [_] true) |
270 | 270 | slurp (fn [_] (throw (ex-info "File not found" {})))] |
271 | | - (is (= "" (#'config/parse-dynamic-string "${file:/nonexistent/file.txt}" "/tmp"))) |
272 | | - (is (= "prefix suffix" (#'config/parse-dynamic-string "prefix ${file:/nonexistent/file.txt} suffix" "/tmp"))))) |
| 271 | + (is (= "" (#'config/parse-dynamic-string "${file:/nonexistent/file.txt}" "/tmp" {}))) |
| 272 | + (is (= "prefix suffix" (#'config/parse-dynamic-string "prefix ${file:/nonexistent/file.txt} suffix" "/tmp" {}))))) |
273 | 273 |
|
274 | 274 | (testing "handles multiple file patterns" |
275 | 275 | (with-redefs [fs/absolute? (fn [_] true) |
|
279 | 279 | "/file2.txt" "content2" |
280 | 280 | (throw (ex-info "File not found" {}))))] |
281 | 281 | (is (= "content1 and content2" |
282 | | - (#'config/parse-dynamic-string "${file:/file1.txt} and ${file:/file2.txt}" "/tmp"))))) |
| 282 | + (#'config/parse-dynamic-string "${file:/file1.txt} and ${file:/file2.txt}" "/tmp" {}))))) |
283 | 283 |
|
284 | 284 | (testing "handles mixed env and file patterns" |
285 | 285 | (with-redefs [config/get-env (fn [env-var] |
|
290 | 290 | "file-value" |
291 | 291 | (throw (ex-info "File not found" {}))))] |
292 | 292 | (is (= "env-value and file-value" |
293 | | - (#'config/parse-dynamic-string "${env:TEST_VAR} and ${file:/file.txt}" "/tmp"))))) |
| 293 | + (#'config/parse-dynamic-string "${env:TEST_VAR} and ${file:/file.txt}" "/tmp" {}))))) |
294 | 294 |
|
295 | 295 | (testing "handles patterns within longer strings" |
296 | 296 | (with-redefs [config/get-env (fn [env-var] |
297 | 297 | (when (= env-var "API_KEY") "secret123"))] |
298 | | - (is (= "Bearer secret123" (#'config/parse-dynamic-string "Bearer ${env:API_KEY}" "/tmp"))))) |
| 298 | + (is (= "Bearer secret123" (#'config/parse-dynamic-string "Bearer ${env:API_KEY}" "/tmp" {}))))) |
299 | 299 |
|
300 | 300 | (testing "handles empty string input" |
301 | | - (is (= "" (#'config/parse-dynamic-string "" "/tmp")))) |
| 301 | + (is (= "" (#'config/parse-dynamic-string "" "/tmp" {})))) |
302 | 302 |
|
303 | 303 | (testing "preserves content with escaped-like patterns that don't match" |
304 | | - (is (= "${notenv:VAR}" (#'config/parse-dynamic-string "${notenv:VAR}" "/tmp"))) |
305 | | - (is (= "${env:}" (#'config/parse-dynamic-string "${env:}" "/tmp")))) |
| 304 | + (is (= "${notenv:VAR}" (#'config/parse-dynamic-string "${notenv:VAR}" "/tmp" {}))) |
| 305 | + (is (= "${env:}" (#'config/parse-dynamic-string "${env:}" "/tmp" {})))) |
306 | 306 |
|
307 | 307 | (testing "replaces classpath pattern with resource content" |
308 | 308 | ;; ECA_VERSION is a real resource file |
309 | | - (let [version-content (#'config/parse-dynamic-string "${classpath:ECA_VERSION}" "/tmp")] |
| 309 | + (let [version-content (#'config/parse-dynamic-string "${classpath:ECA_VERSION}" "/tmp" {})] |
310 | 310 | (is (string? version-content)) |
311 | 311 | (is (seq version-content)))) |
312 | 312 |
|
313 | 313 | (testing "replaces classpath pattern with empty string when resource not found" |
314 | 314 | (with-redefs [logger/warn (fn [& _] nil)] |
315 | | - (is (= "" (#'config/parse-dynamic-string "${classpath:nonexistent/resource.txt}" "/tmp"))) |
316 | | - (is (= "prefix suffix" (#'config/parse-dynamic-string "prefix ${classpath:nonexistent/resource.txt} suffix" "/tmp"))))) |
| 315 | + (is (= "" (#'config/parse-dynamic-string "${classpath:nonexistent/resource.txt}" "/tmp" {}))) |
| 316 | + (is (= "prefix suffix" (#'config/parse-dynamic-string "prefix ${classpath:nonexistent/resource.txt} suffix" "/tmp" {}))))) |
317 | 317 |
|
318 | 318 | (testing "handles multiple classpath patterns" |
319 | 319 | (with-redefs [io/resource (fn [path] |
|
322 | 322 | "resource2.txt" (java.io.ByteArrayInputStream. (.getBytes "content2" "UTF-8")) |
323 | 323 | nil))] |
324 | 324 | (is (= "content1 and content2" |
325 | | - (#'config/parse-dynamic-string "${classpath:resource1.txt} and ${classpath:resource2.txt}" "/tmp"))))) |
| 325 | + (#'config/parse-dynamic-string "${classpath:resource1.txt} and ${classpath:resource2.txt}" "/tmp" {}))))) |
326 | 326 |
|
327 | 327 | (testing "handles classpath patterns within longer strings" |
328 | 328 | (with-redefs [io/resource (fn [path] |
329 | 329 | (when (= path "config/prompt.md") |
330 | 330 | (java.io.ByteArrayInputStream. (.getBytes "# System Prompt\nYou are helpful." "UTF-8"))))] |
331 | 331 | (is (= "# System Prompt\nYou are helpful." |
332 | | - (#'config/parse-dynamic-string "${classpath:config/prompt.md}" "/tmp"))))) |
| 332 | + (#'config/parse-dynamic-string "${classpath:config/prompt.md}" "/tmp" {}))))) |
333 | 333 |
|
334 | 334 | (testing "handles exception when reading classpath resource throws NullPointerException" |
335 | 335 | (with-redefs [logger/warn (fn [& _] nil) |
336 | 336 | io/resource (constantly nil)] |
337 | | - (is (= "" (#'config/parse-dynamic-string "${classpath:error/resource.txt}" "/tmp"))) |
338 | | - (is (= "prefix suffix" (#'config/parse-dynamic-string "prefix ${classpath:error/resource.txt} suffix" "/tmp"))))) |
| 337 | + (is (= "" (#'config/parse-dynamic-string "${classpath:error/resource.txt}" "/tmp" {}))) |
| 338 | + (is (= "prefix suffix" (#'config/parse-dynamic-string "prefix ${classpath:error/resource.txt} suffix" "/tmp" {}))))) |
339 | 339 |
|
340 | 340 | (testing "replaces netrc pattern with credential password" |
341 | | - (with-redefs [secrets/get-credential (fn [key-rc] |
| 341 | + (with-redefs [secrets/get-credential (fn [key-rc _] |
342 | 342 | (when (= key-rc "api.openai.com") |
343 | 343 | "secret-password-123"))] |
344 | | - (is (= "secret-password-123" (#'config/parse-dynamic-string "${netrc:api.openai.com}" "/tmp"))))) |
| 344 | + (is (= "secret-password-123" (#'config/parse-dynamic-string "${netrc:api.openai.com}" "/tmp" {}))))) |
345 | 345 |
|
346 | 346 | (testing "replaces netrc pattern with empty string when credential not found" |
347 | 347 | (with-redefs [secrets/get-credential (constantly nil)] |
348 | | - (is (= "" (#'config/parse-dynamic-string "${netrc:nonexistent.com}" "/tmp"))) |
349 | | - (is (= "prefix suffix" (#'config/parse-dynamic-string "prefix ${netrc:nonexistent.com} suffix" "/tmp"))))) |
| 348 | + (is (= "" (#'config/parse-dynamic-string "${netrc:nonexistent.com}" "/tmp" {}))) |
| 349 | + (is (= "prefix suffix" (#'config/parse-dynamic-string "prefix ${netrc:nonexistent.com} suffix" "/tmp" {}))))) |
350 | 350 |
|
351 | 351 | (testing "handles netrc pattern with login and port" |
352 | | - (with-redefs [secrets/get-credential (fn [key-rc] |
| 352 | + (with-redefs [secrets/get-credential (fn [key-rc _] |
353 | 353 | (case key-rc |
354 | 354 | |
355 | 355 | "api.example.com:8080" "password2" |
356 | 356 | "[email protected]:443" "password3" |
357 | 357 | nil))] |
358 | | - ( is ( = "password1" ( #'config/parse-dynamic-string "${netrc:[email protected]}" "/tmp"))) |
359 | | - (is (= "password2" (#'config/parse-dynamic-string "${netrc:api.example.com:8080}" "/tmp"))) |
360 | | - ( is ( = "password3" ( #'config/parse-dynamic-string "${netrc:[email protected]:443}" "/tmp"))))) |
| 358 | + ( is ( = "password1" ( #'config/parse-dynamic-string "${netrc:[email protected]}" "/tmp" {}))) |
| 359 | + (is (= "password2" (#'config/parse-dynamic-string "${netrc:api.example.com:8080}" "/tmp" {}))) |
| 360 | + ( is ( = "password3" ( #'config/parse-dynamic-string "${netrc:[email protected]:443}" "/tmp" {}))))) |
361 | 361 |
|
362 | 362 | (testing "handles multiple netrc patterns" |
363 | | - (with-redefs [secrets/get-credential (fn [key-rc] |
| 363 | + (with-redefs [secrets/get-credential (fn [key-rc _] |
364 | 364 | (case key-rc |
365 | 365 | "api1.example.com" "password1" |
366 | 366 | "api2.example.com" "password2" |
367 | 367 | nil))] |
368 | 368 | (is (= "password1 and password2" |
369 | | - (#'config/parse-dynamic-string "${netrc:api1.example.com} and ${netrc:api2.example.com}" "/tmp"))))) |
| 369 | + (#'config/parse-dynamic-string "${netrc:api1.example.com} and ${netrc:api2.example.com}" "/tmp" {}))))) |
370 | 370 |
|
371 | 371 | (testing "handles mixed env, file, classpath, and netrc patterns" |
372 | 372 | (with-redefs [config/get-env (fn [env-var] |
|
380 | 380 | (throw (ex-info "File not found" {}))) |
381 | 381 | :else "classpath-value")) |
382 | 382 | io/resource (fn [_] (java.io.ByteArrayInputStream. (.getBytes "classpath-value" "UTF-8"))) |
383 | | - secrets/get-credential (fn [key-rc] |
| 383 | + secrets/get-credential (fn [key-rc _] |
384 | 384 | (when (= key-rc "api.example.com") |
385 | 385 | "netrc-password")) |
386 | 386 | logger/warn (fn [& _] nil)] |
387 | 387 | (is (= "env-value and file-value and classpath-value and netrc-password" |
388 | | - (#'config/parse-dynamic-string "${env:TEST_VAR} and ${file:/file.txt} and ${classpath:resource.txt} and ${netrc:api.example.com}" "/tmp"))))) |
| 388 | + (#'config/parse-dynamic-string "${env:TEST_VAR} and ${file:/file.txt} and ${classpath:resource.txt} and ${netrc:api.example.com}" "/tmp" {}))))) |
389 | 389 |
|
390 | 390 | (testing "handles netrc pattern within longer strings" |
391 | | - (with-redefs [secrets/get-credential (fn [key-rc] |
| 391 | + (with-redefs [secrets/get-credential (fn [key-rc _] |
392 | 392 | (when (= key-rc "api.openai.com") |
393 | 393 | "sk-abc123"))] |
394 | | - (is (= "Bearer sk-abc123" (#'config/parse-dynamic-string "Bearer ${netrc:api.openai.com}" "/tmp"))))) |
| 394 | + (is (= "Bearer sk-abc123" (#'config/parse-dynamic-string "Bearer ${netrc:api.openai.com}" "/tmp" {}))))) |
395 | 395 |
|
396 | 396 | (testing "handles exception when reading netrc credential fails" |
397 | 397 | (with-redefs [logger/warn (fn [& _] nil) |
398 | 398 | secrets/get-credential (fn [_] (throw (ex-info "Netrc error" {})))] |
399 | | - (is (= "" (#'config/parse-dynamic-string "${netrc:api.example.com}" "/tmp"))) |
400 | | - (is (= "prefix suffix" (#'config/parse-dynamic-string "prefix ${netrc:api.example.com} suffix" "/tmp"))))) |
| 399 | + (is (= "" (#'config/parse-dynamic-string "${netrc:api.example.com}" "/tmp" {}))) |
| 400 | + (is (= "prefix suffix" (#'config/parse-dynamic-string "prefix ${netrc:api.example.com} suffix" "/tmp" {}))))) |
401 | 401 |
|
402 | 402 | (testing "handles netrc pattern with special characters in key-rc" |
403 | | - (with-redefs [secrets/get-credential (fn [key-rc] |
| 403 | + (with-redefs [secrets/get-credential (fn [key-rc _] |
404 | 404 | (case key-rc |
405 | 405 | "api-gateway.example-corp.com" "password1" |
406 | 406 | "api_service.example.com" "password2" |
407 | 407 | nil))] |
408 | | - (is (= "password1" (#'config/parse-dynamic-string "${netrc:api-gateway.example-corp.com}" "/tmp"))) |
409 | | - (is (= "password2" (#'config/parse-dynamic-string "${netrc:api_service.example.com}" "/tmp")))))) |
| 408 | + (is (= "password1" (#'config/parse-dynamic-string "${netrc:api-gateway.example-corp.com}" "/tmp" {}))) |
| 409 | + (is (= "password2" (#'config/parse-dynamic-string "${netrc:api_service.example.com}" "/tmp" {})))))) |
0 commit comments