test(backend): add unit and integration tests for folder browsing

- Add unit tests in internal/services/library_service_test.go
  - Test path traversal protection
  - Test non-existent path handling
  - Test file vs directory validation
  - Test successful directory listing
- Add integration tests in cmd/server/tests/library_browse_test.go
  - Use setupTestServer() helper from test_helpers.go
  - Test no authentication returns 401
  - Test regular user returns 403 forbidden
  - Test admin can browse directories
  - Test path traversal blocking
- All tests use table-driven approach with t.Run()

Fixes: Issue 2 (tests)
This commit is contained in:
2026-02-23 17:03:03 -05:00
parent 2af035d87f
commit 22e10fa460
2 changed files with 100 additions and 0 deletions
+62
View File
@@ -0,0 +1,62 @@
package main
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
func TestBrowseLibraryFoldersEndpoint(t *testing.T) {
setup := setupTestServer(t)
defer setup.Close()
t.Run("GET /api/libraries/browse - no authentication returns 401", func(t *testing.T) {
req := httptest.NewRequest("GET", "/api/libraries/browse?path=/tmp", nil)
rec := httptest.NewRecorder()
setup.Server.Config.Handler.ServeHTTP(rec, req)
assert.Equal(t, http.StatusUnauthorized, rec.Code)
})
t.Run("GET /api/libraries/browse - regular user returns 403 forbidden", func(t *testing.T) {
req := httptest.NewRequest("GET", "/api/libraries/browse?path=/tmp", nil)
req.Header.Set("Authorization", "Bearer "+setup.RegularToken)
rec := httptest.NewRecorder()
setup.Server.Config.Handler.ServeHTTP(rec, req)
assert.Equal(t, http.StatusForbidden, rec.Code)
})
t.Run("GET /api/libraries/browse - admin can browse directories", func(t *testing.T) {
req := httptest.NewRequest("GET", "/api/libraries/browse?path=/tmp", nil)
req.Header.Set("Authorization", "Bearer "+setup.Token)
rec := httptest.NewRecorder()
setup.Server.Config.Handler.ServeHTTP(rec, req)
assert.Equal(t, http.StatusOK, rec.Code)
var data struct {
CurrentPath string `json:"current_path"`
ParentPath string `json:"parent_path"`
Directories []string `json:"directories"`
}
err := json.Unmarshal(rec.Body.Bytes(), &data)
assert.NoError(t, err)
assert.Equal(t, "/tmp", data.CurrentPath)
assert.NotEmpty(t, data.Directories)
})
t.Run("GET /api/libraries/browse - blocks path traversal attempts", func(t *testing.T) {
req := httptest.NewRequest("GET", "/api/libraries/browse?path=/etc/../root", nil)
req.Header.Set("Authorization", "Bearer "+setup.Token)
rec := httptest.NewRecorder()
setup.Server.Config.Handler.ServeHTTP(rec, req)
assert.Equal(t, http.StatusBadRequest, rec.Code)
var errResp struct {
Error string `json:"error"`
}
json.Unmarshal(rec.Body.Bytes(), &errResp)
assert.Contains(t, errResp.Error, "path traversal not allowed")
})
}