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.
523 lines
18 KiB
Go
523 lines
18 KiB
Go
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)
|
|
})
|
|
}
|