fixed sonarqube issues
This commit is contained in:
@@ -18,7 +18,7 @@ Your authorization microservice is now **fully horizontally scalable** using Red
|
||||
|
||||
#### 2. Cache Architecture
|
||||
|
||||
```
|
||||
```text
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ Instance 1 │ │ Instance 2 │ │ Instance 3 │
|
||||
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
|
||||
@@ -39,20 +39,20 @@ Your authorization microservice is now **fully horizontally scalable** using Red
|
||||
|
||||
#### 3. Key Features
|
||||
|
||||
**Dual-Layer Caching**
|
||||
#### Dual-Layer Caching
|
||||
|
||||
- Primary: Redis (distributed, shared across instances)
|
||||
- Secondary: Local in-memory (failover, performance boost)
|
||||
- Automatic fallback when Redis unavailable
|
||||
|
||||
**Consistency Guarantees**
|
||||
#### Consistency Guarantees
|
||||
|
||||
- All instances share the same Redis cache
|
||||
- 30-second automatic cache refresh
|
||||
- Manual invalidation via `InvalidateUserCache()`
|
||||
- Force refresh via `RefreshCacheNow()`
|
||||
|
||||
**Performance Optimizations**
|
||||
#### Performance Optimizations
|
||||
|
||||
- JSON serialization for complex objects
|
||||
- 100ms timeout for Redis operations
|
||||
@@ -313,7 +313,7 @@ var (
|
||||
| Medium Cluster | 5 | ~10,000 | <20ms |
|
||||
| Large Cluster | 10+ | ~20,000+ | <25ms |
|
||||
|
||||
_Note: Assumes Redis on same network, PostgreSQL optimized_
|
||||
> **Note:** Assumes Redis on same network, PostgreSQL optimized
|
||||
|
||||
### Cache Effectiveness
|
||||
|
||||
|
||||
+26
-26
@@ -27,9 +27,9 @@ func TestInitAuthService(t *testing.T) {
|
||||
t.Log("InitAuthService completed successfully")
|
||||
}
|
||||
|
||||
func TestAuthorizeHandler_NoJWTClaims(t *testing.T) {
|
||||
func TestAuthorizeHandlerNoJWTClaims(t *testing.T) {
|
||||
// Setup
|
||||
req := httptest.NewRequest("POST", "/v1/auth/check", nil)
|
||||
req := httptest.NewRequest("POST", AuthCheckEndpoint, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
// Execute
|
||||
@@ -37,11 +37,11 @@ func TestAuthorizeHandler_NoJWTClaims(t *testing.T) {
|
||||
|
||||
// Assert
|
||||
if w.Code != http.StatusUnauthorized {
|
||||
t.Errorf("Expected status %d, got %d", http.StatusUnauthorized, w.Code)
|
||||
t.Errorf(ExpectedStatusMessage, http.StatusUnauthorized, w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorizeHandler_InvalidJSON(t *testing.T) {
|
||||
func TestAuthorizeHandlerInvalidJSON(t *testing.T) {
|
||||
// Setup - no need to init service, we're testing JSON parsing before auth
|
||||
claims := &models.Claims{
|
||||
UserID: "user123",
|
||||
@@ -49,7 +49,7 @@ func TestAuthorizeHandler_InvalidJSON(t *testing.T) {
|
||||
Role: "admin",
|
||||
}
|
||||
|
||||
req := httptest.NewRequest("POST", "/v1/auth/check", bytes.NewBufferString("invalid json"))
|
||||
req := httptest.NewRequest("POST", AuthCheckEndpoint, bytes.NewBufferString("invalid json"))
|
||||
ctx := context.WithValue(req.Context(), models.ContextKey("claims"), claims)
|
||||
req = req.WithContext(ctx)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -59,11 +59,11 @@ func TestAuthorizeHandler_InvalidJSON(t *testing.T) {
|
||||
|
||||
// Assert
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("Expected status %d, got %d", http.StatusBadRequest, w.Code)
|
||||
t.Errorf(ExpectedStatusMessage, http.StatusBadRequest, w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorizeHandler_MissingRequiredFields(t *testing.T) {
|
||||
func TestAuthorizeHandlerMissingRequiredFields(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
payload models.AuthorizationContext
|
||||
@@ -91,7 +91,7 @@ func TestAuthorizeHandler_MissingRequiredFields(t *testing.T) {
|
||||
}
|
||||
|
||||
body, _ := json.Marshal(tc.payload)
|
||||
req := httptest.NewRequest("POST", "/v1/auth/check", bytes.NewBuffer(body))
|
||||
req := httptest.NewRequest("POST", AuthCheckEndpoint, bytes.NewBuffer(body))
|
||||
ctx := context.WithValue(req.Context(), models.ContextKey("claims"), claims)
|
||||
req = req.WithContext(ctx)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -99,13 +99,13 @@ func TestAuthorizeHandler_MissingRequiredFields(t *testing.T) {
|
||||
AuthorizeHandler(w, req)
|
||||
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("Expected status %d, got %d", http.StatusBadRequest, w.Code)
|
||||
t.Errorf(ExpectedStatusMessage, http.StatusBadRequest, w.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorizeHandler_UserIDMismatch(t *testing.T) {
|
||||
func TestAuthorizeHandlerUserIDMismatch(t *testing.T) {
|
||||
// Setup
|
||||
claims := &models.Claims{
|
||||
UserID: "user123",
|
||||
@@ -120,7 +120,7 @@ func TestAuthorizeHandler_UserIDMismatch(t *testing.T) {
|
||||
}
|
||||
|
||||
body, _ := json.Marshal(payload)
|
||||
req := httptest.NewRequest("POST", "/v1/auth/check", bytes.NewBuffer(body))
|
||||
req := httptest.NewRequest("POST", AuthCheckEndpoint, bytes.NewBuffer(body))
|
||||
ctx := context.WithValue(req.Context(), models.ContextKey("claims"), claims)
|
||||
req = req.WithContext(ctx)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -130,11 +130,11 @@ func TestAuthorizeHandler_UserIDMismatch(t *testing.T) {
|
||||
|
||||
// Assert
|
||||
if w.Code != http.StatusForbidden {
|
||||
t.Errorf("Expected status %d, got %d", http.StatusForbidden, w.Code)
|
||||
t.Errorf(ExpectedStatusMessage, http.StatusForbidden, w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorizeHandler_NilMaps(t *testing.T) {
|
||||
func TestAuthorizeHandlerNilMaps(t *testing.T) {
|
||||
// Test that nil maps don't cause additional panics beyond missing authService
|
||||
claims := &models.Claims{
|
||||
UserID: "user123",
|
||||
@@ -151,7 +151,7 @@ func TestAuthorizeHandler_NilMaps(t *testing.T) {
|
||||
}
|
||||
|
||||
body, _ := json.Marshal(payload)
|
||||
req := httptest.NewRequest("POST", "/v1/auth/check", bytes.NewBuffer(body))
|
||||
req := httptest.NewRequest("POST", AuthCheckEndpoint, bytes.NewBuffer(body))
|
||||
ctx := context.WithValue(req.Context(), models.ContextKey("claims"), claims)
|
||||
req = req.WithContext(ctx)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -173,7 +173,7 @@ func TestAuthorizeHandler_NilMaps(t *testing.T) {
|
||||
|
||||
// Additional comprehensive test cases
|
||||
|
||||
func TestAuthorizeHandler_EmptyUserID(t *testing.T) {
|
||||
func TestAuthorizeHandlerEmptyUserID(t *testing.T) {
|
||||
claims := &models.Claims{
|
||||
UserID: "user123",
|
||||
Username: "testuser",
|
||||
@@ -187,7 +187,7 @@ func TestAuthorizeHandler_EmptyUserID(t *testing.T) {
|
||||
}
|
||||
|
||||
body, _ := json.Marshal(payload)
|
||||
req := httptest.NewRequest("POST", "/v1/auth/check", bytes.NewBuffer(body))
|
||||
req := httptest.NewRequest("POST", AuthCheckEndpoint, bytes.NewBuffer(body))
|
||||
ctx := context.WithValue(req.Context(), models.ContextKey("claims"), claims)
|
||||
req = req.WithContext(ctx)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -199,7 +199,7 @@ func TestAuthorizeHandler_EmptyUserID(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorizeHandler_EmptyResource(t *testing.T) {
|
||||
func TestAuthorizeHandlerEmptyResource(t *testing.T) {
|
||||
claims := &models.Claims{
|
||||
UserID: "user123",
|
||||
Username: "testuser",
|
||||
@@ -213,7 +213,7 @@ func TestAuthorizeHandler_EmptyResource(t *testing.T) {
|
||||
}
|
||||
|
||||
body, _ := json.Marshal(payload)
|
||||
req := httptest.NewRequest("POST", "/v1/auth/check", bytes.NewBuffer(body))
|
||||
req := httptest.NewRequest("POST", AuthCheckEndpoint, bytes.NewBuffer(body))
|
||||
ctx := context.WithValue(req.Context(), models.ContextKey("claims"), claims)
|
||||
req = req.WithContext(ctx)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -225,7 +225,7 @@ func TestAuthorizeHandler_EmptyResource(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorizeHandler_EmptyAction(t *testing.T) {
|
||||
func TestAuthorizeHandlerEmptyAction(t *testing.T) {
|
||||
claims := &models.Claims{
|
||||
UserID: "user123",
|
||||
Username: "testuser",
|
||||
@@ -239,7 +239,7 @@ func TestAuthorizeHandler_EmptyAction(t *testing.T) {
|
||||
}
|
||||
|
||||
body, _ := json.Marshal(payload)
|
||||
req := httptest.NewRequest("POST", "/v1/auth/check", bytes.NewBuffer(body))
|
||||
req := httptest.NewRequest("POST", AuthCheckEndpoint, bytes.NewBuffer(body))
|
||||
ctx := context.WithValue(req.Context(), models.ContextKey("claims"), claims)
|
||||
req = req.WithContext(ctx)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -251,8 +251,8 @@ func TestAuthorizeHandler_EmptyAction(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorizeHandler_InvalidClaimsType(t *testing.T) {
|
||||
req := httptest.NewRequest("POST", "/v1/auth/check", bytes.NewBufferString(`{"userId":"user123","resource":"doc","action":"read"}`))
|
||||
func TestAuthorizeHandlerInvalidClaimsType(t *testing.T) {
|
||||
req := httptest.NewRequest("POST", AuthCheckEndpoint, bytes.NewBufferString(`{"userId":"user123","resource":"doc","action":"read"}`))
|
||||
|
||||
// Set claims as wrong type
|
||||
ctx := context.WithValue(req.Context(), models.ContextKey("claims"), "invalid_claims_type")
|
||||
@@ -266,7 +266,7 @@ func TestAuthorizeHandler_InvalidClaimsType(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorizeHandler_MalformedJSON(t *testing.T) {
|
||||
func TestAuthorizeHandlerMalformedJSON(t *testing.T) {
|
||||
claims := &models.Claims{
|
||||
UserID: "user123",
|
||||
Username: "testuser",
|
||||
@@ -285,7 +285,7 @@ func TestAuthorizeHandler_MalformedJSON(t *testing.T) {
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
req := httptest.NewRequest("POST", "/v1/auth/check", bytes.NewBufferString(tc.payload))
|
||||
req := httptest.NewRequest("POST", AuthCheckEndpoint, bytes.NewBufferString(tc.payload))
|
||||
ctx := context.WithValue(req.Context(), models.ContextKey("claims"), claims)
|
||||
req = req.WithContext(ctx)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -299,7 +299,7 @@ func TestAuthorizeHandler_MalformedJSON(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorizeHandler_SpecialCharactersInFields(t *testing.T) {
|
||||
func TestAuthorizeHandlerSpecialCharactersInFields(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
userID string
|
||||
@@ -321,7 +321,7 @@ func TestAuthorizeHandler_SpecialCharactersInFields(t *testing.T) {
|
||||
}
|
||||
|
||||
body, _ := json.Marshal(payload)
|
||||
req := httptest.NewRequest("POST", "/v1/auth/check", bytes.NewBuffer(body))
|
||||
req := httptest.NewRequest("POST", AuthCheckEndpoint, bytes.NewBuffer(body))
|
||||
|
||||
// Update claims to match userID
|
||||
testClaims := &models.Claims{
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package handlers
|
||||
|
||||
const (
|
||||
ExpectedStatusMessage = "Expected status %d, got %d"
|
||||
AuthCheckEndpoint = "/v1/auth/check"
|
||||
HealthCheckEndpoint = "/health"
|
||||
StatusMismatchMessage = "status = %v, want %v"
|
||||
FailedToDecodeResponseMessage = "failed to decode response: %v"
|
||||
FailedToCreateMockDBMessage = "failed to create mock db: %v"
|
||||
ReadyCheckEndpoint = "/ready"
|
||||
ExpectedStatus200Message = "Expected status 200, got %d"
|
||||
)
|
||||
+45
-45
@@ -30,7 +30,7 @@ func TestHealthHandler(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
req := httptest.NewRequest(http.MethodGet, "/health", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, HealthCheckEndpoint, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
HealthHandler(w, req)
|
||||
@@ -39,16 +39,16 @@ func TestHealthHandler(t *testing.T) {
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != tt.wantStatus {
|
||||
t.Errorf("status = %v, want %v", resp.StatusCode, tt.wantStatus)
|
||||
t.Errorf(StatusMismatchMessage, resp.StatusCode, tt.wantStatus)
|
||||
}
|
||||
|
||||
var healthResp models.HealthResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&healthResp); err != nil {
|
||||
t.Fatalf("failed to decode response: %v", err)
|
||||
t.Fatalf(FailedToDecodeResponseMessage, err)
|
||||
}
|
||||
|
||||
if healthResp.Status != tt.wantBodyStatus {
|
||||
t.Errorf("status = %v, want %v", healthResp.Status, tt.wantBodyStatus)
|
||||
t.Errorf(StatusMismatchMessage, healthResp.Status, tt.wantBodyStatus)
|
||||
}
|
||||
|
||||
contentType := resp.Header.Get("Content-Type")
|
||||
@@ -59,11 +59,11 @@ func TestHealthHandler(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadyHandler_AllHealthy(t *testing.T) {
|
||||
func TestReadyHandlerAllHealthy(t *testing.T) {
|
||||
// Setup mock DB
|
||||
mockDB, mock, err := sqlmock.New(sqlmock.MonitorPingsOption(true))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create mock db: %v", err)
|
||||
t.Fatalf(FailedToCreateMockDBMessage, err)
|
||||
}
|
||||
defer mockDB.Close()
|
||||
|
||||
@@ -80,7 +80,7 @@ func TestReadyHandler_AllHealthy(t *testing.T) {
|
||||
redisclient.RDB = nil
|
||||
defer func() { redisclient.RDB = originalRedis }()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/ready", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, ReadyCheckEndpoint, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
ReadyHandler(w, req)
|
||||
@@ -90,7 +90,7 @@ func TestReadyHandler_AllHealthy(t *testing.T) {
|
||||
|
||||
var healthResp models.HealthResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&healthResp); err != nil {
|
||||
t.Fatalf("failed to decode response: %v", err)
|
||||
t.Fatalf(FailedToDecodeResponseMessage, err)
|
||||
}
|
||||
|
||||
if healthResp.Services["database"] != "healthy" {
|
||||
@@ -103,11 +103,11 @@ func TestReadyHandler_AllHealthy(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadyHandler_DBUnhealthy(t *testing.T) {
|
||||
func TestReadyHandlerDBUnhealthy(t *testing.T) {
|
||||
// Setup mock DB that fails ping
|
||||
mockDB, mock, err := sqlmock.New(sqlmock.MonitorPingsOption(true))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create mock db: %v", err)
|
||||
t.Fatalf(FailedToCreateMockDBMessage, err)
|
||||
}
|
||||
defer mockDB.Close()
|
||||
|
||||
@@ -124,7 +124,7 @@ func TestReadyHandler_DBUnhealthy(t *testing.T) {
|
||||
redisclient.RDB = nil
|
||||
defer func() { redisclient.RDB = originalRedis }()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/ready", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, ReadyCheckEndpoint, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
ReadyHandler(w, req)
|
||||
@@ -133,12 +133,12 @@ func TestReadyHandler_DBUnhealthy(t *testing.T) {
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusServiceUnavailable {
|
||||
t.Errorf("status = %v, want %v", resp.StatusCode, http.StatusServiceUnavailable)
|
||||
t.Errorf(StatusMismatchMessage, resp.StatusCode, http.StatusServiceUnavailable)
|
||||
}
|
||||
|
||||
var healthResp models.HealthResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&healthResp); err != nil {
|
||||
t.Fatalf("failed to decode response: %v", err)
|
||||
t.Fatalf(FailedToDecodeResponseMessage, err)
|
||||
}
|
||||
|
||||
if healthResp.Status != "not_ready" {
|
||||
@@ -154,7 +154,7 @@ func TestReadyHandler_DBUnhealthy(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadyHandler_DBNotInitialized(t *testing.T) {
|
||||
func TestReadyHandlerDBNotInitialized(t *testing.T) {
|
||||
// Save original and set to nil
|
||||
originalDB := db.DB
|
||||
db.DB = nil
|
||||
@@ -164,7 +164,7 @@ func TestReadyHandler_DBNotInitialized(t *testing.T) {
|
||||
redisclient.RDB = nil
|
||||
defer func() { redisclient.RDB = originalRedis }()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/ready", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, ReadyCheckEndpoint, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
ReadyHandler(w, req)
|
||||
@@ -173,12 +173,12 @@ func TestReadyHandler_DBNotInitialized(t *testing.T) {
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusServiceUnavailable {
|
||||
t.Errorf("status = %v, want %v", resp.StatusCode, http.StatusServiceUnavailable)
|
||||
t.Errorf(StatusMismatchMessage, resp.StatusCode, http.StatusServiceUnavailable)
|
||||
}
|
||||
|
||||
var healthResp models.HealthResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&healthResp); err != nil {
|
||||
t.Fatalf("failed to decode response: %v", err)
|
||||
t.Fatalf(FailedToDecodeResponseMessage, err)
|
||||
}
|
||||
|
||||
if healthResp.Status != "not_ready" {
|
||||
@@ -194,7 +194,7 @@ func TestReadyHandler_DBNotInitialized(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadyHandler_ContentType(t *testing.T) {
|
||||
func TestReadyHandlerContentType(t *testing.T) {
|
||||
originalDB := db.DB
|
||||
db.DB = nil
|
||||
defer func() { db.DB = originalDB }()
|
||||
@@ -203,7 +203,7 @@ func TestReadyHandler_ContentType(t *testing.T) {
|
||||
redisclient.RDB = nil
|
||||
defer func() { redisclient.RDB = originalRedis }()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/ready", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, ReadyCheckEndpoint, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
ReadyHandler(w, req)
|
||||
@@ -219,19 +219,19 @@ func TestReadyHandler_ContentType(t *testing.T) {
|
||||
|
||||
// Additional comprehensive test cases
|
||||
|
||||
func TestHealthHandler_MultipleRequests(t *testing.T) {
|
||||
func TestHealthHandlerMultipleRequests(t *testing.T) {
|
||||
// Test that multiple concurrent requests work correctly
|
||||
concurrency := 10
|
||||
done := make(chan bool, concurrency)
|
||||
|
||||
for i := 0; i < concurrency; i++ {
|
||||
go func() {
|
||||
req := httptest.NewRequest(http.MethodGet, "/health", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, HealthCheckEndpoint, nil)
|
||||
w := httptest.NewRecorder()
|
||||
HealthHandler(w, req)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Errorf("Expected status 200, got %d", w.Code)
|
||||
t.Errorf(ExpectedStatus200Message, w.Code)
|
||||
}
|
||||
done <- true
|
||||
}()
|
||||
@@ -242,12 +242,12 @@ func TestHealthHandler_MultipleRequests(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHealthHandler_DifferentMethods(t *testing.T) {
|
||||
func TestHealthHandlerDifferentMethods(t *testing.T) {
|
||||
methods := []string{"GET", "POST", "PUT", "DELETE", "PATCH"}
|
||||
|
||||
for _, method := range methods {
|
||||
t.Run(method, func(t *testing.T) {
|
||||
req := httptest.NewRequest(method, "/health", nil)
|
||||
req := httptest.NewRequest(method, HealthCheckEndpoint, nil)
|
||||
w := httptest.NewRecorder()
|
||||
HealthHandler(w, req)
|
||||
|
||||
@@ -259,14 +259,14 @@ func TestHealthHandler_DifferentMethods(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHealthHandler_ResponseFormat(t *testing.T) {
|
||||
req := httptest.NewRequest(http.MethodGet, "/health", nil)
|
||||
func TestHealthHandlerResponseFormat(t *testing.T) {
|
||||
req := httptest.NewRequest(http.MethodGet, HealthCheckEndpoint, nil)
|
||||
w := httptest.NewRecorder()
|
||||
HealthHandler(w, req)
|
||||
|
||||
var response models.HealthResponse
|
||||
if err := json.NewDecoder(w.Body).Decode(&response); err != nil {
|
||||
t.Fatalf("Failed to decode response: %v", err)
|
||||
t.Fatalf(FailedToDecodeResponseMessage, err)
|
||||
}
|
||||
|
||||
if response.Status == "" {
|
||||
@@ -278,10 +278,10 @@ func TestHealthHandler_ResponseFormat(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadyHandler_DatabaseTimeout(t *testing.T) {
|
||||
func TestReadyHandlerDatabaseTimeout(t *testing.T) {
|
||||
mockDB, mock, err := sqlmock.New(sqlmock.MonitorPingsOption(true))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create mock db: %v", err)
|
||||
t.Fatalf(FailedToCreateMockDBMessage, err)
|
||||
}
|
||||
defer mockDB.Close()
|
||||
|
||||
@@ -296,7 +296,7 @@ func TestReadyHandler_DatabaseTimeout(t *testing.T) {
|
||||
redisclient.RDB = nil
|
||||
defer func() { redisclient.RDB = originalRedis }()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/ready", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, ReadyCheckEndpoint, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
// This should timeout and return unhealthy
|
||||
@@ -307,7 +307,7 @@ func TestReadyHandler_DatabaseTimeout(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadyHandler_BothServicesHealthy(t *testing.T) {
|
||||
func TestReadyHandlerBothServicesHealthy(t *testing.T) {
|
||||
// Use miniredis for Redis mock
|
||||
mr, err := miniredis.Run()
|
||||
if err != nil {
|
||||
@@ -325,7 +325,7 @@ func TestReadyHandler_BothServicesHealthy(t *testing.T) {
|
||||
// Setup mock database
|
||||
mockDB, mock, err := sqlmock.New(sqlmock.MonitorPingsOption(true))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create mock DB: %v", err)
|
||||
t.Fatalf(FailedToCreateMockDBMessage, err)
|
||||
}
|
||||
defer mockDB.Close()
|
||||
|
||||
@@ -336,13 +336,13 @@ func TestReadyHandler_BothServicesHealthy(t *testing.T) {
|
||||
// Expect ping
|
||||
mock.ExpectPing()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/ready", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, ReadyCheckEndpoint, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
ReadyHandler(w, req)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Errorf("Expected status 200, got %d", w.Code)
|
||||
t.Errorf(ExpectedStatus200Message, w.Code)
|
||||
}
|
||||
|
||||
var response models.HealthResponse
|
||||
@@ -357,7 +357,7 @@ func TestReadyHandler_BothServicesHealthy(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadyHandler_NilDatabaseAndRedis(t *testing.T) {
|
||||
func TestReadyHandlerNilDatabaseAndRedis(t *testing.T) {
|
||||
originalDB := db.DB
|
||||
db.DB = nil
|
||||
defer func() { db.DB = originalDB }()
|
||||
@@ -366,7 +366,7 @@ func TestReadyHandler_NilDatabaseAndRedis(t *testing.T) {
|
||||
redisclient.RDB = nil
|
||||
defer func() { redisclient.RDB = originalRedis }()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/ready", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, ReadyCheckEndpoint, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
ReadyHandler(w, req)
|
||||
@@ -377,7 +377,7 @@ func TestReadyHandler_NilDatabaseAndRedis(t *testing.T) {
|
||||
|
||||
var response models.HealthResponse
|
||||
if err := json.NewDecoder(w.Body).Decode(&response); err != nil {
|
||||
t.Fatalf("Failed to decode response: %v", err)
|
||||
t.Fatalf(FailedToDecodeResponseMessage, err)
|
||||
}
|
||||
|
||||
// The handler returns "not_ready" when services are down
|
||||
@@ -386,7 +386,7 @@ func TestReadyHandler_NilDatabaseAndRedis(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadyHandler_ResponseStructure(t *testing.T) {
|
||||
func TestReadyHandlerResponseStructure(t *testing.T) {
|
||||
originalDB := db.DB
|
||||
db.DB = nil
|
||||
defer func() { db.DB = originalDB }()
|
||||
@@ -395,7 +395,7 @@ func TestReadyHandler_ResponseStructure(t *testing.T) {
|
||||
redisclient.RDB = nil
|
||||
defer func() { redisclient.RDB = originalRedis }()
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/ready", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, ReadyCheckEndpoint, nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
ReadyHandler(w, req)
|
||||
@@ -403,7 +403,7 @@ func TestReadyHandler_ResponseStructure(t *testing.T) {
|
||||
// Verify response is valid JSON
|
||||
var response map[string]interface{}
|
||||
if err := json.NewDecoder(w.Body).Decode(&response); err != nil {
|
||||
t.Fatalf("Failed to decode response: %v", err)
|
||||
t.Fatalf(FailedToDecodeResponseMessage, err)
|
||||
}
|
||||
|
||||
// Check that response has expected fields
|
||||
@@ -412,8 +412,8 @@ func TestReadyHandler_ResponseStructure(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHealthHandler_WithCustomHeaders(t *testing.T) {
|
||||
req := httptest.NewRequest(http.MethodGet, "/health", nil)
|
||||
func TestHealthHandlerWithCustomHeaders(t *testing.T) {
|
||||
req := httptest.NewRequest(http.MethodGet, HealthCheckEndpoint, nil)
|
||||
req.Header.Set("X-Request-ID", "test-123")
|
||||
req.Header.Set("User-Agent", "Test-Agent/1.0")
|
||||
|
||||
@@ -421,11 +421,11 @@ func TestHealthHandler_WithCustomHeaders(t *testing.T) {
|
||||
HealthHandler(w, req)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Errorf("Expected status 200, got %d", w.Code)
|
||||
t.Errorf(ExpectedStatus200Message, w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadyHandler_ConcurrentRequests(t *testing.T) {
|
||||
func TestReadyHandlerConcurrentRequests(t *testing.T) {
|
||||
originalDB := db.DB
|
||||
db.DB = nil
|
||||
defer func() { db.DB = originalDB }()
|
||||
@@ -439,7 +439,7 @@ func TestReadyHandler_ConcurrentRequests(t *testing.T) {
|
||||
|
||||
for i := 0; i < concurrency; i++ {
|
||||
go func() {
|
||||
req := httptest.NewRequest(http.MethodGet, "/ready", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, ReadyCheckEndpoint, nil)
|
||||
w := httptest.NewRecorder()
|
||||
ReadyHandler(w, req)
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ func TestNewCircuitBreaker(t *testing.T) {
|
||||
t.Errorf("timeout = %v, want %v", cb.timeout, tt.timeout)
|
||||
}
|
||||
if cb.state != tt.wantState {
|
||||
t.Errorf("state = %v, want %v", cb.state, tt.wantState)
|
||||
t.Errorf(StateMismatchMessage, cb.state, tt.wantState)
|
||||
}
|
||||
if cb.resetTimeout != 30*time.Second {
|
||||
t.Errorf("resetTimeout = %v, want %v", cb.resetTimeout, 30*time.Second)
|
||||
@@ -57,7 +57,7 @@ func TestNewCircuitBreaker(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_Call_Success(t *testing.T) {
|
||||
func TestCircuitBreakerCallSuccess(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 3, 1*time.Second)
|
||||
|
||||
successFn := func() error {
|
||||
@@ -70,15 +70,15 @@ func TestCircuitBreaker_Call_Success(t *testing.T) {
|
||||
}
|
||||
|
||||
if GetState(cb) != StateClosed {
|
||||
t.Errorf("state = %v, want %v", GetState(cb), StateClosed)
|
||||
t.Errorf(StateMismatchMessage, GetState(cb), StateClosed)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_Call_FailuresOpenCircuit(t *testing.T) {
|
||||
func TestCircuitBreakerCallFailuresOpenCircuit(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 3, 1*time.Second)
|
||||
|
||||
failFn := func() error {
|
||||
return errors.New("service error")
|
||||
return errors.New(ServiceError)
|
||||
}
|
||||
|
||||
// First 2 failures - circuit should stay closed
|
||||
@@ -98,7 +98,7 @@ func TestCircuitBreaker_Call_FailuresOpenCircuit(t *testing.T) {
|
||||
t.Error("Call() expected error, got nil")
|
||||
}
|
||||
if GetState(cb) != StateOpen {
|
||||
t.Errorf("state = %v, want %v", GetState(cb), StateOpen)
|
||||
t.Errorf(StateMismatchMessage, GetState(cb), StateOpen)
|
||||
}
|
||||
|
||||
// Next call should immediately return circuit breaker error
|
||||
@@ -108,12 +108,12 @@ func TestCircuitBreaker_Call_FailuresOpenCircuit(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_Call_OpenToHalfOpen(t *testing.T) {
|
||||
func TestCircuitBreakerCallOpenToHalfOpen(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 2, 1*time.Second)
|
||||
cb.resetTimeout = 100 * time.Millisecond // Shorter reset for testing
|
||||
|
||||
failFn := func() error {
|
||||
return errors.New("service error")
|
||||
return errors.New(ServiceError)
|
||||
}
|
||||
|
||||
// Open the circuit
|
||||
@@ -121,7 +121,7 @@ func TestCircuitBreaker_Call_OpenToHalfOpen(t *testing.T) {
|
||||
Call(cb, failFn)
|
||||
|
||||
if GetState(cb) != StateOpen {
|
||||
t.Fatalf("state = %v, want %v", GetState(cb), StateOpen)
|
||||
t.Fatalf(StateMismatchMessage, GetState(cb), StateOpen)
|
||||
}
|
||||
|
||||
// Wait for reset timeout
|
||||
@@ -139,16 +139,16 @@ func TestCircuitBreaker_Call_OpenToHalfOpen(t *testing.T) {
|
||||
|
||||
// Should now be closed
|
||||
if GetState(cb) != StateClosed {
|
||||
t.Errorf("state = %v, want %v", GetState(cb), StateClosed)
|
||||
t.Errorf(StateMismatchMessage, GetState(cb), StateClosed)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_Call_HalfOpenFailReturnsToOpen(t *testing.T) {
|
||||
func TestCircuitBreakerCallHalfOpenFailReturnsToOpen(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 2, 1*time.Second)
|
||||
cb.resetTimeout = 100 * time.Millisecond
|
||||
|
||||
failFn := func() error {
|
||||
return errors.New("service error")
|
||||
return errors.New(ServiceError)
|
||||
}
|
||||
|
||||
// Open the circuit
|
||||
@@ -156,7 +156,7 @@ func TestCircuitBreaker_Call_HalfOpenFailReturnsToOpen(t *testing.T) {
|
||||
Call(cb, failFn)
|
||||
|
||||
if GetState(cb) != StateOpen {
|
||||
t.Fatalf("state = %v, want %v", GetState(cb), StateOpen)
|
||||
t.Fatalf(StateMismatchMessage, GetState(cb), StateOpen)
|
||||
}
|
||||
|
||||
// Wait for reset timeout to transition to HalfOpen
|
||||
@@ -169,15 +169,15 @@ func TestCircuitBreaker_Call_HalfOpenFailReturnsToOpen(t *testing.T) {
|
||||
}
|
||||
|
||||
if GetState(cb) != StateOpen {
|
||||
t.Errorf("state = %v, want %v", GetState(cb), StateOpen)
|
||||
t.Errorf(StateMismatchMessage, GetState(cb), StateOpen)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_Call_GradualFailureReduction(t *testing.T) {
|
||||
func TestCircuitBreakerCallGradualFailureReduction(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 5, 1*time.Second)
|
||||
|
||||
failFn := func() error {
|
||||
return errors.New("service error")
|
||||
return errors.New(ServiceError)
|
||||
}
|
||||
successFn := func() error {
|
||||
return nil
|
||||
@@ -208,7 +208,7 @@ func TestCircuitBreaker_Call_GradualFailureReduction(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_GetState(t *testing.T) {
|
||||
func TestCircuitBreakerGetState(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setupFunc func(*CircuitBreaker)
|
||||
@@ -250,7 +250,7 @@ func TestCircuitBreaker_GetState(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_Reset(t *testing.T) {
|
||||
func TestCircuitBreakerReset(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 2, 1*time.Second)
|
||||
|
||||
// Open the circuit
|
||||
@@ -261,7 +261,7 @@ func TestCircuitBreaker_Reset(t *testing.T) {
|
||||
Call(cb, failFn)
|
||||
|
||||
if GetState(cb) != StateOpen {
|
||||
t.Fatalf("state = %v, want %v", GetState(cb), StateOpen)
|
||||
t.Fatalf(StateMismatchMessage, GetState(cb), StateOpen)
|
||||
}
|
||||
|
||||
// Reset the circuit breaker
|
||||
@@ -280,7 +280,7 @@ func TestCircuitBreaker_Reset(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreakerError_Error(t *testing.T) {
|
||||
func TestCircuitBreakerErrorError(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
err *CircuitBreakerError
|
||||
@@ -350,7 +350,7 @@ func TestIsCircuitBreakerError(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_Concurrency(t *testing.T) {
|
||||
func TestCircuitBreakerConcurrency(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 10, 1*time.Second)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
@@ -397,7 +397,7 @@ func TestCircuitBreaker_Concurrency(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_OpenCircuitRejectsImmediately(t *testing.T) {
|
||||
func TestCircuitBreakerOpenCircuitRejectsImmediately(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 1, 1*time.Second)
|
||||
|
||||
// Open the circuit
|
||||
@@ -407,7 +407,7 @@ func TestCircuitBreaker_OpenCircuitRejectsImmediately(t *testing.T) {
|
||||
Call(cb, failFn)
|
||||
|
||||
if GetState(cb) != StateOpen {
|
||||
t.Fatalf("state = %v, want %v", GetState(cb), StateOpen)
|
||||
t.Fatalf(StateMismatchMessage, GetState(cb), StateOpen)
|
||||
}
|
||||
|
||||
// Try calling with a function that should not execute
|
||||
@@ -428,7 +428,7 @@ func TestCircuitBreaker_OpenCircuitRejectsImmediately(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCircuitBreaker_Call_Success(b *testing.B) {
|
||||
func BenchmarkCircuitBreakerCallSuccess(b *testing.B) {
|
||||
cb := NewCircuitBreaker("test", 5, 1*time.Second)
|
||||
fn := func() error {
|
||||
return nil
|
||||
@@ -440,7 +440,7 @@ func BenchmarkCircuitBreaker_Call_Success(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCircuitBreaker_Call_Open(b *testing.B) {
|
||||
func BenchmarkCircuitBreakerCallOpen(b *testing.B) {
|
||||
cb := NewCircuitBreaker("test", 1, 1*time.Second)
|
||||
|
||||
// Open the circuit
|
||||
@@ -458,7 +458,7 @@ func BenchmarkCircuitBreaker_Call_Open(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_StateTransitions(t *testing.T) {
|
||||
func TestCircuitBreakerStateTransitions(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 2, 1*time.Second)
|
||||
cb.resetTimeout = 100 * time.Millisecond
|
||||
|
||||
@@ -497,7 +497,7 @@ func TestCircuitBreaker_StateTransitions(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_ZeroMaxFailures(t *testing.T) {
|
||||
func TestCircuitBreakerZeroMaxFailures(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 0, 1*time.Second)
|
||||
|
||||
// Even one failure should open circuit when maxFailures is 0
|
||||
@@ -512,7 +512,7 @@ func TestCircuitBreaker_ZeroMaxFailures(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_NegativeMaxFailures(t *testing.T) {
|
||||
func TestCircuitBreakerNegativeMaxFailures(t *testing.T) {
|
||||
// Negative maxFailures should be treated as invalid, but won't panic
|
||||
cb := NewCircuitBreaker("test", -1, 1*time.Second)
|
||||
|
||||
@@ -526,7 +526,7 @@ func TestCircuitBreaker_NegativeMaxFailures(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_VeryShortTimeout(t *testing.T) {
|
||||
func TestCircuitBreakerVeryShortTimeout(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 1, 1*time.Nanosecond)
|
||||
cb.resetTimeout = 1 * time.Nanosecond
|
||||
|
||||
@@ -542,7 +542,7 @@ func TestCircuitBreaker_VeryShortTimeout(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_MultipleSuccessesAfterFailure(t *testing.T) {
|
||||
func TestCircuitBreakerMultipleSuccessesAfterFailure(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 3, 1*time.Second)
|
||||
|
||||
// Add one failure
|
||||
@@ -570,7 +570,7 @@ func TestCircuitBreaker_MultipleSuccessesAfterFailure(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_HighConcurrency(t *testing.T) {
|
||||
func TestCircuitBreakerHighConcurrency(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 10, 1*time.Second)
|
||||
|
||||
concurrency := 100
|
||||
@@ -608,7 +608,7 @@ func TestCircuitBreaker_HighConcurrency(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_HalfOpenSingleRequest(t *testing.T) {
|
||||
func TestCircuitBreakerHalfOpenSingleRequest(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 1, 1*time.Second)
|
||||
cb.resetTimeout = 50 * time.Millisecond
|
||||
|
||||
@@ -637,7 +637,7 @@ func TestCircuitBreaker_HalfOpenSingleRequest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_SuccessResetsFailureCount(t *testing.T) {
|
||||
func TestCircuitBreakerSuccessResetsFailureCount(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 3, 1*time.Second)
|
||||
|
||||
// 2 failures
|
||||
@@ -674,7 +674,7 @@ func TestCircuitBreaker_SuccessResetsFailureCount(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_DifferentErrorTypes(t *testing.T) {
|
||||
func TestCircuitBreakerDifferentErrorTypes(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 2, 1*time.Second)
|
||||
|
||||
// Different error types should all count as failures
|
||||
@@ -686,7 +686,7 @@ func TestCircuitBreaker_DifferentErrorTypes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_NilFunction(t *testing.T) {
|
||||
func TestCircuitBreakerNilFunction(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 3, 1*time.Second)
|
||||
|
||||
// Should handle nil function gracefully (though this is a programming error)
|
||||
@@ -699,7 +699,7 @@ func TestCircuitBreaker_NilFunction(t *testing.T) {
|
||||
Call(cb, nil)
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_LongRunningOperation(t *testing.T) {
|
||||
func TestCircuitBreakerLongRunningOperation(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 2, 100*time.Millisecond)
|
||||
|
||||
// Test that timeout works during operation
|
||||
@@ -715,7 +715,7 @@ func TestCircuitBreaker_LongRunningOperation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCircuitBreaker_RapidStateChanges(t *testing.T) {
|
||||
func TestCircuitBreakerRapidStateChanges(t *testing.T) {
|
||||
cb := NewCircuitBreaker("test", 1, 1*time.Second)
|
||||
cb.resetTimeout = 10 * time.Millisecond
|
||||
|
||||
|
||||
@@ -8,4 +8,6 @@ const (
|
||||
ErrorEncodingResponse = "Error encoding response"
|
||||
ErrorFailedtoLogLoginEvent = "Failed to log login event"
|
||||
WarningLabel = "WARNING:"
|
||||
StateMismatchMessage = "state = %v, want %v"
|
||||
ServiceError = "service error"
|
||||
)
|
||||
|
||||
@@ -68,7 +68,7 @@ func TestLogInfo(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogInfo_NoEnvironment(t *testing.T) {
|
||||
func TestLogInfoNoEnvironment(t *testing.T) {
|
||||
// Setup
|
||||
os.Unsetenv("GO_ENV")
|
||||
|
||||
@@ -188,7 +188,7 @@ func TestLogError(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogError_WithNilError(t *testing.T) {
|
||||
func TestLogErrorWithNilError(t *testing.T) {
|
||||
// Setup
|
||||
os.Setenv("GO_ENV", "development")
|
||||
defer os.Unsetenv("GO_ENV")
|
||||
@@ -223,7 +223,7 @@ func TestLogFatal(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestLogging_EnvironmentCheck(t *testing.T) {
|
||||
func TestLoggingEnvironmentCheck(t *testing.T) {
|
||||
// Test that all logging functions check for GO_ENV
|
||||
originalEnv := os.Getenv("GO_ENV")
|
||||
defer func() {
|
||||
|
||||
@@ -74,7 +74,7 @@ func TestGetClientIP(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckRateLimit_AllowedRequests(t *testing.T) {
|
||||
func TestCheckRateLimitAllowedRequests(t *testing.T) {
|
||||
db, mock := redismock.NewClientMock()
|
||||
originalRedis := redisclient.RDB
|
||||
redisclient.RDB = db
|
||||
@@ -107,7 +107,7 @@ func TestCheckRateLimit_AllowedRequests(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckRateLimit_ExceedsLimit(t *testing.T) {
|
||||
func TestCheckRateLimitExceedsLimit(t *testing.T) {
|
||||
db, mock := redismock.NewClientMock()
|
||||
originalRedis := redisclient.RDB
|
||||
redisclient.RDB = db
|
||||
@@ -140,7 +140,7 @@ func TestCheckRateLimit_ExceedsLimit(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckRateLimit_RedisError(t *testing.T) {
|
||||
func TestCheckRateLimitRedisError(t *testing.T) {
|
||||
db, mock := redismock.NewClientMock()
|
||||
originalRedis := redisclient.RDB
|
||||
redisclient.RDB = db
|
||||
@@ -169,7 +169,7 @@ func TestCheckRateLimit_RedisError(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRateLimiterMiddleware_RedisNotAvailable(t *testing.T) {
|
||||
func TestRateLimiterMiddlewareRedisNotAvailable(t *testing.T) {
|
||||
originalRedis := redisclient.RDB
|
||||
redisclient.RDB = nil
|
||||
defer func() { redisclient.RDB = originalRedis }()
|
||||
@@ -243,7 +243,7 @@ func TestRateLimiterMiddleware_AllowsRequest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRateLimiterMiddleware_BlocksRequest(t *testing.T) {
|
||||
func TestRateLimiterMiddlewareBlocksRequest(t *testing.T) {
|
||||
db, mock := redismock.NewClientMock()
|
||||
originalRedis := redisclient.RDB
|
||||
redisclient.RDB = db
|
||||
@@ -285,7 +285,7 @@ func TestRateLimiterMiddleware_BlocksRequest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRateLimiterMiddleware_FailsOpenOnError(t *testing.T) {
|
||||
func TestRateLimiterMiddlewareFailsOpenOnError(t *testing.T) {
|
||||
db, mock := redismock.NewClientMock()
|
||||
originalRedis := redisclient.RDB
|
||||
redisclient.RDB = db
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
func TestInit_DefaultValues(t *testing.T) {
|
||||
func TestInitDefaultValues(t *testing.T) {
|
||||
// Save original values
|
||||
originalHost := os.Getenv("REDIS_HOST")
|
||||
originalPort := os.Getenv("REDIS_PORT")
|
||||
|
||||
Reference in New Issue
Block a user