veza/veza-backend-api/internal/handlers/config_reload_test.go

219 lines
5.6 KiB
Go

package handlers
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"veza-backend-api/internal/config"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"go.uber.org/zap"
)
// MockConfigReloader mocks ConfigReloader
type MockConfigReloader struct {
mock.Mock
}
func (m *MockConfigReloader) ReloadAll() error {
args := m.Called()
return args.Error(0)
}
func (m *MockConfigReloader) ReloadLogLevel() error {
args := m.Called()
return args.Error(0)
}
func (m *MockConfigReloader) ReloadRateLimits() error {
args := m.Called()
return args.Error(0)
}
func (m *MockConfigReloader) GetCurrentConfig() *config.ReloadableConfig {
args := m.Called()
if args.Get(0) == nil {
return nil
}
return args.Get(0).(*config.ReloadableConfig)
}
func setupTestConfigReloadRouter(mockReloader *MockConfigReloader) *gin.Engine {
gin.SetMode(gin.TestMode)
router := gin.New()
logger := zap.NewNop()
handler := NewConfigReloadHandlerWithInterface(mockReloader, logger)
api := router.Group("/api/v1/config")
{
api.POST("/reload", handler.ReloadConfig())
api.GET("/", handler.GetConfig())
}
return router
}
func TestConfigReloadHandler_ReloadConfig_All(t *testing.T) {
// Setup
mockReloader := new(MockConfigReloader)
router := setupTestConfigReloadRouter(mockReloader)
reqBody := map[string]string{"type": "all"}
expectedConfig := &config.ReloadableConfig{
LogLevel: "info",
RateLimitLimit: 100,
RateLimitWindow: 60,
}
mockReloader.On("ReloadAll").Return(nil)
mockReloader.On("GetCurrentConfig").Return(expectedConfig)
body, _ := json.Marshal(reqBody)
// Execute
req, _ := http.NewRequest("POST", "/api/v1/config/reload", bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
// Assert
assert.Equal(t, http.StatusOK, w.Code)
var response map[string]interface{}
err := json.Unmarshal(w.Body.Bytes(), &response)
assert.NoError(t, err)
assert.True(t, response["success"].(bool))
mockReloader.AssertExpectations(t)
}
func TestConfigReloadHandler_ReloadConfig_LogLevel(t *testing.T) {
// Setup
mockReloader := new(MockConfigReloader)
router := setupTestConfigReloadRouter(mockReloader)
reqBody := map[string]string{"type": "log_level"}
expectedConfig := &config.ReloadableConfig{
LogLevel: "debug",
RateLimitLimit: 100,
RateLimitWindow: 60,
}
mockReloader.On("ReloadLogLevel").Return(nil)
mockReloader.On("GetCurrentConfig").Return(expectedConfig)
body, _ := json.Marshal(reqBody)
// Execute
req, _ := http.NewRequest("POST", "/api/v1/config/reload", bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
// Assert
assert.Equal(t, http.StatusOK, w.Code)
mockReloader.AssertExpectations(t)
}
func TestConfigReloadHandler_ReloadConfig_RateLimits(t *testing.T) {
// Setup
mockReloader := new(MockConfigReloader)
router := setupTestConfigReloadRouter(mockReloader)
reqBody := map[string]string{"type": "rate_limits"}
expectedConfig := &config.ReloadableConfig{
LogLevel: "info",
RateLimitLimit: 200,
RateLimitWindow: 120,
}
mockReloader.On("ReloadRateLimits").Return(nil)
mockReloader.On("GetCurrentConfig").Return(expectedConfig)
body, _ := json.Marshal(reqBody)
// Execute
req, _ := http.NewRequest("POST", "/api/v1/config/reload", bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
// Assert
assert.Equal(t, http.StatusOK, w.Code)
mockReloader.AssertExpectations(t)
}
func TestConfigReloadHandler_ReloadConfig_InvalidType(t *testing.T) {
// Setup
mockReloader := new(MockConfigReloader)
router := setupTestConfigReloadRouter(mockReloader)
reqBody := map[string]string{"type": "invalid"}
body, _ := json.Marshal(reqBody)
// Execute
req, _ := http.NewRequest("POST", "/api/v1/config/reload", bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
// Assert
assert.Equal(t, http.StatusBadRequest, w.Code)
mockReloader.AssertNotCalled(t, "ReloadAll")
mockReloader.AssertNotCalled(t, "ReloadLogLevel")
mockReloader.AssertNotCalled(t, "ReloadRateLimits")
}
func TestConfigReloadHandler_ReloadConfig_ServiceError(t *testing.T) {
// Setup
mockReloader := new(MockConfigReloader)
router := setupTestConfigReloadRouter(mockReloader)
reqBody := map[string]string{"type": "all"}
mockReloader.On("ReloadAll").Return(assert.AnError)
body, _ := json.Marshal(reqBody)
// Execute
req, _ := http.NewRequest("POST", "/api/v1/config/reload", bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
// Assert
assert.Equal(t, http.StatusInternalServerError, w.Code)
mockReloader.AssertExpectations(t)
}
func TestConfigReloadHandler_GetConfig_Success(t *testing.T) {
// Setup
mockReloader := new(MockConfigReloader)
router := setupTestConfigReloadRouter(mockReloader)
expectedConfig := &config.ReloadableConfig{
LogLevel: "info",
RateLimitLimit: 100,
RateLimitWindow: 60,
}
mockReloader.On("GetCurrentConfig").Return(expectedConfig)
// Execute
req, _ := http.NewRequest("GET", "/api/v1/config/", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
// Assert
assert.Equal(t, http.StatusOK, w.Code)
var response map[string]interface{}
err := json.Unmarshal(w.Body.Bytes(), &response)
assert.NoError(t, err)
assert.True(t, response["success"].(bool))
mockReloader.AssertExpectations(t)
}