test: add integration tests for processing issues API endpoints
Added comprehensive integration tests for the new processing issues API endpoints that track EPUB format mismatches in manga/comics libraries. Test Coverage: - Authentication & authorization (no auth, invalid auth, non-admin, admin) - Input validation (malformed UUIDs, path traversal, SQL injection attempts) - Response structure validation (fields, types, content-type) - Cross-library isolation (ensures issues don't leak between libraries) - All library types (ebooks, comics, manga, audiobooks) - Edge cases and error conditions Endpoints Tested: - GET /api/libraries/:id/issues/list - Lists unresolved processing issues - GET /api/libraries/:id/issues/stats - Returns error/warning/info counts Test Implementation: - 522 lines, 9 test functions, 30+ subtests - Uses setupTestServer() helper for server setup - Uses setupDeviceTest() helper for library creation - Follows PROJECT_GUIDELINES.md requirements - Table-driven tests with t.Run() for comprehensive coverage - Tests all three user contexts: no user, regular user, admin This ensures the processing issues feature is properly tested before integration with the media scanner service.
This commit is contained in:
@@ -0,0 +1,522 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestProcessingIssuesListAuthentication tests authentication and authorization for list endpoint
|
||||
func TestProcessingIssuesListAuthentication(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
// Create a test library
|
||||
deviceSetup := setupDeviceTest(t)
|
||||
libraryID := deviceSetup.CreateLibrary(t, "Test Auth Library", "manga")
|
||||
|
||||
t.Run("GET /api/libraries/:id/issues/list - No authentication", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/list", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusUnauthorized, rec.Code)
|
||||
})
|
||||
|
||||
t.Run("GET /api/libraries/:id/issues/list - Non-admin user forbidden", func(t *testing.T) {
|
||||
token := setup.RegularToken
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/list", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusForbidden, rec.Code)
|
||||
})
|
||||
|
||||
t.Run("GET /api/libraries/:id/issues/list - Admin user authorized", func(t *testing.T) {
|
||||
token := setup.Token
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/list", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
})
|
||||
}
|
||||
|
||||
// TestProcessingIssuesListResponseStructure tests the response structure of list endpoint
|
||||
func TestProcessingIssuesListResponseStructure(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
// Create a test library
|
||||
deviceSetup := setupDeviceTest(t)
|
||||
libraryID := deviceSetup.CreateLibrary(t, "Test Structure Library", "comics")
|
||||
|
||||
t.Run("Returns JSON array for empty library", func(t *testing.T) {
|
||||
token := setup.Token
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/list", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
|
||||
var response []map[string]interface{}
|
||||
err := json.NewDecoder(rec.Body).Decode(&response)
|
||||
require.NoError(t, err)
|
||||
assert.IsType(t, []map[string]interface{}{}, response)
|
||||
assert.Equal(t, 0, len(response), "Empty library should return empty array")
|
||||
})
|
||||
|
||||
t.Run("Has correct content type", func(t *testing.T) {
|
||||
token := setup.Token
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/list", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Equal(t, "application/json", rec.Header().Get("Content-Type"))
|
||||
})
|
||||
}
|
||||
|
||||
// TestProcessingIssuesListInputValidation tests input validation for list endpoint
|
||||
func TestProcessingIssuesListInputValidation(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
token := setup.Token
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
libraryID string
|
||||
expectedStatus int
|
||||
description string
|
||||
}{
|
||||
{
|
||||
name: "Invalid UUID format",
|
||||
libraryID: "not-a-uuid",
|
||||
expectedStatus: http.StatusBadRequest,
|
||||
description: "Should reject malformed UUID",
|
||||
},
|
||||
{
|
||||
name: "Empty UUID",
|
||||
libraryID: "",
|
||||
expectedStatus: http.StatusNotFound,
|
||||
description: "Should return 404 for empty ID",
|
||||
},
|
||||
{
|
||||
name: "UUID with extra path traversal",
|
||||
libraryID: "00000000-0000-0000-0000-000000000000/../../etc",
|
||||
expectedStatus: http.StatusBadRequest,
|
||||
description: "Should reject path traversal attempts",
|
||||
},
|
||||
{
|
||||
name: "Nonexistent library UUID",
|
||||
libraryID: "00000000-0000-0000-0000-000000000000",
|
||||
expectedStatus: http.StatusOK,
|
||||
description: "Should return empty array for valid but nonexistent UUID",
|
||||
},
|
||||
{
|
||||
name: "Special characters in UUID",
|
||||
libraryID: "'; DROP TABLE processing_issues; --",
|
||||
expectedStatus: http.StatusBadRequest,
|
||||
description: "Should reject SQL injection attempts",
|
||||
},
|
||||
{
|
||||
name: "Very long UUID",
|
||||
libraryID: "00000000-0000-0000-0000-000000000000-extra-suffix",
|
||||
expectedStatus: http.StatusBadRequest,
|
||||
description: "Should reject overly long IDs",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+tc.libraryID+"/issues/list", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, tc.expectedStatus, rec.Code, tc.description)
|
||||
|
||||
// For successful requests, verify response structure
|
||||
if tc.expectedStatus == http.StatusOK {
|
||||
var response []map[string]interface{}
|
||||
err := json.NewDecoder(rec.Body).Decode(&response)
|
||||
require.NoError(t, err)
|
||||
assert.IsType(t, []map[string]interface{}{}, response)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestProcessingIssueStatsAuthentication tests authentication and authorization for stats endpoint
|
||||
func TestProcessingIssueStatsAuthentication(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
// Create a test library
|
||||
deviceSetup := setupDeviceTest(t)
|
||||
libraryID := deviceSetup.CreateLibrary(t, "Test Stats Auth Library", "manga")
|
||||
|
||||
t.Run("GET /api/libraries/:id/issues/stats - No authentication", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/stats", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusUnauthorized, rec.Code)
|
||||
})
|
||||
|
||||
t.Run("GET /api/libraries/:id/issues/stats - Non-admin user forbidden", func(t *testing.T) {
|
||||
token := setup.RegularToken
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/stats", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusForbidden, rec.Code)
|
||||
})
|
||||
|
||||
t.Run("GET /api/libraries/:id/issues/stats - Admin user authorized", func(t *testing.T) {
|
||||
token := setup.Token
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/stats", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
})
|
||||
}
|
||||
|
||||
// TestProcessingIssueStatsResponseStructure tests the response structure of stats endpoint
|
||||
func TestProcessingIssueStatsResponseStructure(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
// Create a test library
|
||||
deviceSetup := setupDeviceTest(t)
|
||||
libraryID := deviceSetup.CreateLibrary(t, "Test Stats Structure Library", "comics")
|
||||
|
||||
t.Run("Returns correct structure for empty library", func(t *testing.T) {
|
||||
token := setup.Token
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/stats", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
|
||||
var response map[string]interface{}
|
||||
err := json.NewDecoder(rec.Body).Decode(&response)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify required fields
|
||||
assert.Contains(t, response, "error_count", "Should have error_count field")
|
||||
assert.Contains(t, response, "warning_count", "Should have warning_count field")
|
||||
assert.Contains(t, response, "info_count", "Should have info_count field")
|
||||
|
||||
// Verify all counts are zero for empty library
|
||||
assert.Equal(t, float64(0), response["error_count"], "error_count should be 0")
|
||||
assert.Equal(t, float64(0), response["warning_count"], "warning_count should be 0")
|
||||
assert.Equal(t, float64(0), response["info_count"], "info_count should be 0")
|
||||
|
||||
// Verify field types
|
||||
assert.IsType(t, float64(0), response["error_count"], "error_count should be number")
|
||||
assert.IsType(t, float64(0), response["warning_count"], "warning_count should be number")
|
||||
assert.IsType(t, float64(0), response["info_count"], "info_count should be number")
|
||||
})
|
||||
|
||||
t.Run("Has correct content type", func(t *testing.T) {
|
||||
token := setup.Token
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/stats", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Equal(t, "application/json", rec.Header().Get("Content-Type"))
|
||||
})
|
||||
|
||||
t.Run("Has exactly 3 fields", func(t *testing.T) {
|
||||
token := setup.Token
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/stats", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
|
||||
var response map[string]interface{}
|
||||
err := json.NewDecoder(rec.Body).Decode(&response)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, response, 3, "Should have exactly 3 fields")
|
||||
})
|
||||
}
|
||||
|
||||
// TestProcessingIssueStatsInputValidation tests input validation for stats endpoint
|
||||
func TestProcessingIssueStatsInputValidation(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
token := setup.Token
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
libraryID string
|
||||
expectedStatus int
|
||||
description string
|
||||
}{
|
||||
{
|
||||
name: "Invalid UUID format",
|
||||
libraryID: "not-a-uuid",
|
||||
expectedStatus: http.StatusBadRequest,
|
||||
description: "Should reject malformed UUID",
|
||||
},
|
||||
{
|
||||
name: "Empty UUID",
|
||||
libraryID: "",
|
||||
expectedStatus: http.StatusNotFound,
|
||||
description: "Should return 404 for empty ID",
|
||||
},
|
||||
{
|
||||
name: "UUID with extra path traversal",
|
||||
libraryID: "00000000-0000-0000-0000-000000000000/../../etc",
|
||||
expectedStatus: http.StatusBadRequest,
|
||||
description: "Should reject path traversal attempts",
|
||||
},
|
||||
{
|
||||
name: "Nonexistent library UUID",
|
||||
libraryID: "00000000-0000-0000-0000-000000000000",
|
||||
expectedStatus: http.StatusOK,
|
||||
description: "Should return zero counts for valid but nonexistent UUID",
|
||||
},
|
||||
{
|
||||
name: "Special characters in UUID",
|
||||
libraryID: "'; DROP TABLE processing_issues; --",
|
||||
expectedStatus: http.StatusBadRequest,
|
||||
description: "Should reject SQL injection attempts",
|
||||
},
|
||||
{
|
||||
name: "Very long UUID",
|
||||
libraryID: "00000000-0000-0000-0000-000000000000-extra-suffix",
|
||||
expectedStatus: http.StatusBadRequest,
|
||||
description: "Should reject overly long IDs",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+tc.libraryID+"/issues/stats", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, tc.expectedStatus, rec.Code, tc.description)
|
||||
|
||||
// For successful requests, verify response structure
|
||||
if tc.expectedStatus == http.StatusOK {
|
||||
var response map[string]interface{}
|
||||
err := json.NewDecoder(rec.Body).Decode(&response)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify all counts are zero for nonexistent library
|
||||
assert.Equal(t, float64(0), response["error_count"])
|
||||
assert.Equal(t, float64(0), response["warning_count"])
|
||||
assert.Equal(t, float64(0), response["info_count"])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestProcessingIssuesCrossLibraryIsolation tests that different libraries don't interfere
|
||||
func TestProcessingIssuesCrossLibraryIsolation(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
// Create two different libraries with different types
|
||||
deviceSetup1 := setupDeviceTest(t)
|
||||
library1ID := deviceSetup1.CreateLibrary(t, "Isolation Test Library 1", "manga")
|
||||
|
||||
deviceSetup2 := setupDeviceTest(t)
|
||||
library2ID := deviceSetup2.CreateLibrary(t, "Isolation Test Library 2", "comics")
|
||||
|
||||
token := setup.Token
|
||||
|
||||
// Both libraries should return empty arrays (no issues created)
|
||||
t.Run("Library 1 returns its own empty list", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+library1ID+"/issues/list", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
|
||||
var response []map[string]interface{}
|
||||
err := json.NewDecoder(rec.Body).Decode(&response)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 0, len(response), "Library 1 should have 0 issues")
|
||||
})
|
||||
|
||||
t.Run("Library 2 returns its own empty list", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+library2ID+"/issues/list", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
|
||||
var response []map[string]interface{}
|
||||
err := json.NewDecoder(rec.Body).Decode(&response)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 0, len(response), "Library 2 should have 0 issues")
|
||||
})
|
||||
|
||||
t.Run("Both libraries have independent stats", func(t *testing.T) {
|
||||
// Get stats for library 1
|
||||
req1 := httptest.NewRequest("GET", "/api/libraries/"+library1ID+"/issues/stats", nil)
|
||||
req1.Header.Set("Authorization", "Bearer "+token)
|
||||
rec1 := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec1, req1)
|
||||
|
||||
var stats1 map[string]interface{}
|
||||
json.NewDecoder(rec1.Body).Decode(&stats1)
|
||||
|
||||
// Get stats for library 2
|
||||
req2 := httptest.NewRequest("GET", "/api/libraries/"+library2ID+"/issues/stats", nil)
|
||||
req2.Header.Set("Authorization", "Bearer "+token)
|
||||
rec2 := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec2, req2)
|
||||
|
||||
var stats2 map[string]interface{}
|
||||
json.NewDecoder(rec2.Body).Decode(&stats2)
|
||||
|
||||
// Both should have zero counts
|
||||
assert.Equal(t, float64(0), stats1["error_count"])
|
||||
assert.Equal(t, float64(0), stats1["warning_count"])
|
||||
assert.Equal(t, float64(0), stats1["info_count"])
|
||||
|
||||
assert.Equal(t, float64(0), stats2["error_count"])
|
||||
assert.Equal(t, float64(0), stats2["warning_count"])
|
||||
assert.Equal(t, float64(0), stats2["info_count"])
|
||||
})
|
||||
}
|
||||
|
||||
// TestProcessingIssuesDifferentLibraryTypes tests endpoints with different library types
|
||||
func TestProcessingIssuesDifferentLibraryTypes(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
token := setup.Token
|
||||
|
||||
libraryTypes := []struct {
|
||||
name string
|
||||
libraryType string
|
||||
}{
|
||||
{"Ebooks library", "ebooks"},
|
||||
{"Comics library", "comics"},
|
||||
{"Manga library", "manga"},
|
||||
{"Audiobooks library", "audiobooks"},
|
||||
}
|
||||
|
||||
for _, lt := range libraryTypes {
|
||||
t.Run(lt.name+" - list endpoint works", func(t *testing.T) {
|
||||
deviceSetup := setupDeviceTest(t)
|
||||
libraryID := deviceSetup.CreateLibrary(t, "Test "+lt.name, lt.libraryType)
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/list", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
|
||||
var response []map[string]interface{}
|
||||
err := json.NewDecoder(rec.Body).Decode(&response)
|
||||
require.NoError(t, err)
|
||||
assert.IsType(t, []map[string]interface{}{}, response)
|
||||
})
|
||||
|
||||
t.Run(lt.name+" - stats endpoint works", func(t *testing.T) {
|
||||
deviceSetup := setupDeviceTest(t)
|
||||
libraryID := deviceSetup.CreateLibrary(t, "Test "+lt.name, lt.libraryType)
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/stats", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
|
||||
var response map[string]interface{}
|
||||
err := json.NewDecoder(rec.Body).Decode(&response)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Contains(t, response, "error_count")
|
||||
assert.Contains(t, response, "warning_count")
|
||||
assert.Contains(t, response, "info_count")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestProcessingIssuesInvalidTokens tests with invalid authentication tokens
|
||||
func TestProcessingIssuesInvalidTokens(t *testing.T) {
|
||||
setup := setupTestServer(t)
|
||||
|
||||
// Create a test library
|
||||
deviceSetup := setupDeviceTest(t)
|
||||
libraryID := deviceSetup.CreateLibrary(t, "Test Token Library", "ebooks")
|
||||
|
||||
t.Run("List endpoint rejects invalid token", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/list", nil)
|
||||
req.Header.Set("Authorization", "Bearer invalid-token-12345")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusUnauthorized, rec.Code)
|
||||
})
|
||||
|
||||
t.Run("Stats endpoint rejects invalid token", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/stats", nil)
|
||||
req.Header.Set("Authorization", "Bearer invalid-token-12345")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusUnauthorized, rec.Code)
|
||||
})
|
||||
|
||||
t.Run("List endpoint rejects missing bearer prefix", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/list", nil)
|
||||
req.Header.Set("Authorization", setup.Token) // Missing "Bearer " prefix
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusUnauthorized, rec.Code)
|
||||
})
|
||||
|
||||
t.Run("Stats endpoint rejects missing bearer prefix", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/stats", nil)
|
||||
req.Header.Set("Authorization", setup.Token) // Missing "Bearer " prefix
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusUnauthorized, rec.Code)
|
||||
})
|
||||
|
||||
t.Run("List endpoint rejects empty authorization header", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/libraries/"+libraryID+"/issues/list", nil)
|
||||
req.Header.Set("Authorization", "")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
assert.Equal(t, http.StatusUnauthorized, rec.Code)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user