151 lines
3.9 KiB
Go
151 lines
3.9 KiB
Go
package handlers
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/stretchr/testify/assert"
|
|
"go.uber.org/zap"
|
|
|
|
"veza-backend-api/internal/dto"
|
|
)
|
|
|
|
func TestBindAndValidateJSON_Validation(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
logger := zap.NewNop()
|
|
commonHandler := NewCommonHandler(logger)
|
|
|
|
// Test case struct
|
|
type TestRequest struct {
|
|
Name string `json:"name" validate:"required,min=3"`
|
|
Email string `json:"email" validate:"required,email"`
|
|
Age int `json:"age" validate:"gte=18"`
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
payload interface{}
|
|
expectedStatus int
|
|
expectedError string
|
|
checkDetails bool
|
|
}{
|
|
{
|
|
name: "Valid Request",
|
|
payload: TestRequest{
|
|
Name: "John Doe",
|
|
Email: "john@example.com",
|
|
Age: 25,
|
|
},
|
|
expectedStatus: http.StatusOK,
|
|
},
|
|
{
|
|
name: "Missing Required Fields",
|
|
payload: map[string]interface{}{
|
|
"age": 25,
|
|
},
|
|
expectedStatus: http.StatusBadRequest, // or 422 depending on implementation, BindAndValidateJSON returns 400 for validation error wrapper
|
|
expectedError: "Validation failed",
|
|
checkDetails: true,
|
|
},
|
|
{
|
|
name: "Invalid Email",
|
|
payload: TestRequest{
|
|
Name: "John",
|
|
Email: "not-an-email",
|
|
Age: 25,
|
|
},
|
|
expectedStatus: http.StatusBadRequest,
|
|
expectedError: "Validation failed",
|
|
checkDetails: true,
|
|
},
|
|
{
|
|
name: "Min Length Violation",
|
|
payload: TestRequest{
|
|
Name: "Jo",
|
|
Email: "john@example.com",
|
|
Age: 25,
|
|
},
|
|
expectedStatus: http.StatusBadRequest,
|
|
expectedError: "Validation failed",
|
|
checkDetails: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
|
|
jsonBytes, _ := json.Marshal(tt.payload)
|
|
c.Request = httptest.NewRequest("POST", "/test", bytes.NewBuffer(jsonBytes))
|
|
c.Request.Header.Set("Content-Type", "application/json")
|
|
|
|
var req TestRequest
|
|
appErr := commonHandler.BindAndValidateJSON(c, &req)
|
|
|
|
if tt.expectedStatus == http.StatusOK {
|
|
assert.Nil(t, appErr)
|
|
} else {
|
|
assert.NotNil(t, appErr)
|
|
// Verify error response format by actually calling RespondWithAppError logic simulation
|
|
// Or check AppError properties
|
|
assert.Contains(t, appErr.Message, tt.expectedError)
|
|
|
|
if tt.checkDetails {
|
|
// check logic in commonHandler.BindAndValidateJSON
|
|
// It returns apperrors.NewValidationError which puts details in Details field
|
|
assert.NotEmpty(t, appErr.Details, "Should have validation details")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBindAndValidateJSON_DTOs(t *testing.T) {
|
|
// Verify actual DTOs used in handlers
|
|
gin.SetMode(gin.TestMode)
|
|
logger := zap.NewNop()
|
|
commonHandler := NewCommonHandler(logger)
|
|
|
|
t.Run("RegisterRequest_Invalid", func(t *testing.T) {
|
|
payload := dto.RegisterRequest{
|
|
Username: "ab", // Too short
|
|
Email: "bad-email",
|
|
Password: "short",
|
|
}
|
|
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
jsonBytes, _ := json.Marshal(commonHandler) // Mistake in previous line logic, fix payload
|
|
jsonBytes, _ = json.Marshal(payload)
|
|
|
|
c.Request = httptest.NewRequest("POST", "/register", bytes.NewBuffer(jsonBytes))
|
|
var req dto.RegisterRequest
|
|
appErr := commonHandler.BindAndValidateJSON(c, &req)
|
|
|
|
assert.NotNil(t, appErr)
|
|
// Should catch Username min, Email format, Password min
|
|
assert.NotEmpty(t, appErr.Details)
|
|
})
|
|
|
|
t.Run("LoginRequest_Invalid", func(t *testing.T) {
|
|
payload := dto.LoginRequest{
|
|
Email: "bad-email",
|
|
}
|
|
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
jsonBytes, _ := json.Marshal(payload)
|
|
|
|
c.Request = httptest.NewRequest("POST", "/login", bytes.NewBuffer(jsonBytes))
|
|
var req dto.LoginRequest
|
|
appErr := commonHandler.BindAndValidateJSON(c, &req)
|
|
|
|
assert.NotNil(t, appErr)
|
|
assert.NotEmpty(t, appErr.Details)
|
|
})
|
|
}
|