Tests
This commit is contained in:
@@ -26,6 +26,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -910,5 +911,103 @@ func TestVerifyCheck_RoleChangeToVerified(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Password Length Tests (Registration)
|
||||
// =============================================================================
|
||||
|
||||
// TestRegister_PasswordLength_NoMinimum verifies that registration accepts passwords
|
||||
// of any length (no minimum). The business decision is to not enforce a minimum.
|
||||
// bcrypt handles passwords up to 72 chars internally (truncates longer ones).
|
||||
func TestRegister_PasswordLength_NoMinimum(t *testing.T) {
|
||||
cleanup := setupTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
handler := http.HandlerFunc(RegisterHandler)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
password string
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "1_char_password",
|
||||
password: "x",
|
||||
expectError: false, // No minimum enforced
|
||||
},
|
||||
{
|
||||
name: "5_char_password",
|
||||
password: "short",
|
||||
expectError: false, // No minimum enforced
|
||||
},
|
||||
{
|
||||
name: "72_char_password_exact_bcrypt_limit",
|
||||
password: strings.Repeat("a", 72),
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "73_char_password_exceeds_limit",
|
||||
password: strings.Repeat("a", 73),
|
||||
expectError: true, // Exceeds bcrypt limit
|
||||
},
|
||||
{
|
||||
name: "100_char_password_exceeds_limit",
|
||||
password: strings.Repeat("a", 100),
|
||||
expectError: true, // Exceeds bcrypt limit
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
body := RegisterRequest{
|
||||
FirstName: "Test",
|
||||
LastName: "User",
|
||||
Email: fmt.Sprintf("test-%s@test.com", tt.name),
|
||||
Password: tt.password,
|
||||
Phone: "07123456789",
|
||||
DateOfBirth: "1990-01-15",
|
||||
AgreedToPolicy: true,
|
||||
}
|
||||
|
||||
w := makeRequest(handler, "POST", "/api/register", body)
|
||||
|
||||
if tt.expectError {
|
||||
if w.Code == http.StatusCreated {
|
||||
t.Errorf("expected non-201 status for password '%s', got 201", tt.password)
|
||||
}
|
||||
} else {
|
||||
if w.Code != http.StatusCreated {
|
||||
t.Errorf("expected status 201 for password len=%d, got %d. body: %s", len(tt.password), w.Code, w.Body.String())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestRegister_EmptyPassword verifies that an empty password is rejected
|
||||
// because it's a required field (not because of minimum length).
|
||||
func TestRegister_EmptyPassword(t *testing.T) {
|
||||
cleanup := setupTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
handler := http.HandlerFunc(RegisterHandler)
|
||||
|
||||
body := RegisterRequest{
|
||||
FirstName: "Test",
|
||||
LastName: "User",
|
||||
Email: "empty@test.com",
|
||||
Password: "", // Empty - should fail as required field
|
||||
Phone: "07123456789",
|
||||
DateOfBirth: "1990-01-15",
|
||||
AgreedToPolicy: true,
|
||||
}
|
||||
|
||||
w := makeRequest(handler, "POST", "/api/register", body)
|
||||
|
||||
// Empty password fails because it's a required field
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("expected status 400 for empty password, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure test compilation - import pgxpool to avoid unused import
|
||||
var _ = func() *pgxpool.Pool { return nil }
|
||||
|
||||
@@ -92,11 +92,16 @@ func RegisterHandler(w http.ResponseWriter, r *http.Request) {
|
||||
req.DateOfBirth = strings.TrimSpace(req.DateOfBirth)
|
||||
|
||||
// Check required fields
|
||||
if req.FirstName == "" || req.LastName == "" || req.Email == "" || req.Phone == "" || req.DateOfBirth == "" {
|
||||
if req.FirstName == "" || req.LastName == "" || req.Email == "" || req.Phone == "" || req.DateOfBirth == "" || req.Password == "" {
|
||||
http.Error(w, "all fields are required", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Password must not exceed bcrypt's 72-byte limit
|
||||
if len(req.Password) > 72 {
|
||||
http.Error(w, "password must be 72 characters or less", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
// Validate name (unicode letters, spaces, hyphen, apostrophe, dot)
|
||||
nameRegex := regexp.MustCompile(`^[\p{L}\p{M}\s\-'\.]+$`)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user