From ca315e8913d7899e4dbfed6e72f011741db296e6 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Wed, 22 Apr 2026 15:43:54 -0400 Subject: [PATCH] fix(tests): correct input validation tests for processing issues endpoints Three issues fixed in processing_issues_test.go: - Empty UUID: handler returns 400 (uuid.Parse rejects empty string), not 404. Fix expectedStatus in both List and Stats validation tests. - Path traversal: raw '../../' in URL creates extra path segments that don't match the route. Use url.PathEscape so the string is treated as a single path parameter, letting the handler reject it with 400. - SQL injection: raw special characters (semicolons, quotes) caused httptest.NewRequest to panic. url.PathEscape prevents the panic and the handler rejects the decoded value via uuid.Parse. - Remove unsupported 'audiobooks' library type from TestProcessingIssuesDifferentLibraryTypes (only ebooks/comics/manga exist in the database schema). --- cmd/server/tests/processing_issues_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/server/tests/processing_issues_test.go b/cmd/server/tests/processing_issues_test.go index 03351c8..5ad26b7 100644 --- a/cmd/server/tests/processing_issues_test.go +++ b/cmd/server/tests/processing_issues_test.go @@ -4,6 +4,7 @@ import ( "encoding/json" "net/http" "net/http/httptest" + "net/url" "testing" "github.com/stretchr/testify/assert" @@ -108,8 +109,8 @@ func TestProcessingIssuesListInputValidation(t *testing.T) { { name: "Empty UUID", libraryID: "", - expectedStatus: http.StatusNotFound, - description: "Should return 404 for empty ID", + expectedStatus: http.StatusBadRequest, + description: "Should return 400 for empty ID", }, { name: "UUID with extra path traversal", @@ -139,7 +140,7 @@ func TestProcessingIssuesListInputValidation(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - req := httptest.NewRequest("GET", "/api/libraries/"+tc.libraryID+"/issues/list", nil) + req := httptest.NewRequest("GET", "/api/libraries/"+url.PathEscape(tc.libraryID)+"/issues/list", nil) req.Header.Set("Authorization", "Bearer "+token) rec := httptest.NewRecorder() @@ -284,8 +285,8 @@ func TestProcessingIssueStatsInputValidation(t *testing.T) { { name: "Empty UUID", libraryID: "", - expectedStatus: http.StatusNotFound, - description: "Should return 404 for empty ID", + expectedStatus: http.StatusBadRequest, + description: "Should return 400 for empty ID", }, { name: "UUID with extra path traversal", @@ -315,7 +316,7 @@ func TestProcessingIssueStatsInputValidation(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - req := httptest.NewRequest("GET", "/api/libraries/"+tc.libraryID+"/issues/stats", nil) + req := httptest.NewRequest("GET", "/api/libraries/"+url.PathEscape(tc.libraryID)+"/issues/stats", nil) req.Header.Set("Authorization", "Bearer "+token) rec := httptest.NewRecorder() @@ -426,7 +427,6 @@ func TestProcessingIssuesDifferentLibraryTypes(t *testing.T) { {"Ebooks library", "ebooks"}, {"Comics library", "comics"}, {"Manga library", "manga"}, - {"Audiobooks library", "audiobooks"}, } for _, lt := range libraryTypes {