fix:修复注册逻辑和HTTP状态码问题

核心修复:
- 调整注册流程检查顺序,先验证用户存在性再验证验证码
- 修复HTTP状态码问题,业务失败时返回正确的错误状态码
- 优化错误处理逻辑,提供更准确的错误信息

主要变更:
- 登录核心服务:重构注册方法,优化检查顺序避免验证码无效消费
- 用户服务:分离用户创建和重复检查逻辑,提高代码复用性
- 登录控制器:修复HTTP状态码处理,根据业务结果返回正确状态码
- API文档:更新注册接口说明和错误响应示例
- 测试脚本:优化测试逻辑和注释说明

修复效果:
- 用户已存在时立即返回正确错误信息,不消费验证码
- API响应状态码准确反映业务执行结果
- 错误信息更加用户友好和准确
- 验证码使用更加合理和高效

测试验证:
- 所有核心功能测试通过
- 注册逻辑修复验证成功
- HTTP状态码修复验证成功
- 限流功能正常工作
This commit is contained in:
moyin
2025-12-24 20:39:23 +08:00
parent e537e782a9
commit 404ef5d3e0
5 changed files with 297 additions and 66 deletions

View File

@@ -1,53 +1,133 @@
# Test register API fix
# Test register API fix - Core functionality test
# 测试注册API修复 - 核心功能测试
#
# 主要测试内容:
# 1. 用户注册(无邮箱)- 应该成功
# 2. 用户注册(有邮箱但无验证码)- 应该失败并返回正确错误信息
# 3. 用户存在性检查 - 应该在验证码验证之前进行,返回"用户名已存在"
# 4. 邮箱验证码完整流程 - 验证码生成、注册、重复邮箱检查
#
# 修复验证:
# - 用户存在检查现在在验证码验证之前执行
# - 验证码不会因为用户已存在而被无效消费
# - 错误信息更加准确和用户友好
$baseUrl = "http://localhost:3000"
Write-Host "Testing register API fix..." -ForegroundColor Green
Write-Host "🧪 Testing Register API Fix" -ForegroundColor Green
Write-Host "============================" -ForegroundColor Green
# Test 1: Register with email but no verification code (should return 400)
Write-Host "`nTest 1: Register with email but no verification code" -ForegroundColor Yellow
$registerData1 = @{
username = "testuser1"
password = "password123"
nickname = "Test User 1"
email = "test1@example.com"
} | ConvertTo-Json
try {
$response1 = Invoke-RestMethod -Uri "$baseUrl/auth/register" -Method POST -Body $registerData1 -ContentType "application/json" -ErrorAction Stop
Write-Host "Status: 200/201 (Unexpected success)" -ForegroundColor Red
Write-Host "Response: $($response1 | ConvertTo-Json -Depth 3)" -ForegroundColor Red
} catch {
$statusCode = $_.Exception.Response.StatusCode.value__
Write-Host "Status Code: $statusCode" -ForegroundColor $(if ($statusCode -eq 400) { "Green" } else { "Red" })
# Helper function to handle API responses
function Test-ApiCall {
param(
[string]$TestName,
[string]$Url,
[string]$Body,
[int]$ExpectedStatus = 200
)
if ($_.Exception.Response) {
$reader = New-Object System.IO.StreamReader($_.Exception.Response.GetResponseStream())
$responseBody = $reader.ReadToEnd()
Write-Host "Response: $responseBody" -ForegroundColor Gray
Write-Host "`n📋 $TestName" -ForegroundColor Yellow
try {
$response = Invoke-RestMethod -Uri $Url -Method POST -Body $Body -ContentType "application/json" -ErrorAction Stop
Write-Host "✅ SUCCESS ($(if ($response.success) { 'true' } else { 'false' }))" -ForegroundColor Green
Write-Host "Message: $($response.message)" -ForegroundColor Cyan
return $response
} catch {
$statusCode = $_.Exception.Response.StatusCode.value__
Write-Host "❌ FAILED ($statusCode)" -ForegroundColor $(if ($statusCode -eq $ExpectedStatus) { "Yellow" } else { "Red" })
if ($_.Exception.Response) {
$stream = $_.Exception.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($stream)
$responseBody = $reader.ReadToEnd()
$reader.Close()
$stream.Close()
if ($responseBody) {
try {
$errorResponse = $responseBody | ConvertFrom-Json
Write-Host "Message: $($errorResponse.message)" -ForegroundColor Cyan
Write-Host "Error Code: $($errorResponse.error_code)" -ForegroundColor Gray
return $errorResponse
} catch {
Write-Host "Raw Response: $responseBody" -ForegroundColor Gray
}
} else {
Write-Host "Empty response body" -ForegroundColor Gray
}
}
return $null
}
}
# Test 2: Register without email (should return 201)
Write-Host "`nTest 2: Register without email" -ForegroundColor Yellow
$registerData2 = @{
username = "testuser2"
password = "password123"
nickname = "Test User 2"
} | ConvertTo-Json
# Clear throttle first
Write-Host "`n🔄 Clearing throttle records..." -ForegroundColor Blue
try {
$response2 = Invoke-RestMethod -Uri "$baseUrl/auth/register" -Method POST -Body $registerData2 -ContentType "application/json" -ErrorAction Stop
Write-Host "Status: 200/201 (Success)" -ForegroundColor Green
Write-Host "Response: $($response2 | ConvertTo-Json -Depth 3)" -ForegroundColor Green
Invoke-RestMethod -Uri "$baseUrl/auth/debug-clear-throttle" -Method POST | Out-Null
Write-Host "✅ Throttle cleared" -ForegroundColor Green
} catch {
$statusCode = $_.Exception.Response.StatusCode.value__
Write-Host "Status Code: $statusCode (Unexpected failure)" -ForegroundColor Red
Write-Host "⚠️ Could not clear throttle" -ForegroundColor Yellow
}
# Test 1: Register without email (should succeed)
$result1 = Test-ApiCall -TestName "Register without email" -Url "$baseUrl/auth/register" -Body (@{
username = "testuser_$(Get-Random)"
password = "password123"
nickname = "Test User"
} | ConvertTo-Json)
# Test 2: Register with email but no verification code (should fail)
$result2 = Test-ApiCall -TestName "Register with email but no verification code" -Url "$baseUrl/auth/register" -Body (@{
username = "testuser_$(Get-Random)"
password = "password123"
nickname = "Test User"
email = "test@example.com"
} | ConvertTo-Json) -ExpectedStatus 400
# Test 3: Try to register with existing username (should fail with correct error)
if ($result1 -and $result1.success) {
$existingUsername = ($result1.data.user.username)
$result3 = Test-ApiCall -TestName "Register with existing username ($existingUsername)" -Url "$baseUrl/auth/register" -Body (@{
username = $existingUsername
password = "password123"
nickname = "Duplicate User"
} | ConvertTo-Json) -ExpectedStatus 400
if ($_.Exception.Response) {
$reader = New-Object System.IO.StreamReader($_.Exception.Response.GetResponseStream())
$responseBody = $reader.ReadToEnd()
Write-Host "Response: $responseBody" -ForegroundColor Red
if ($result3 -and $result3.message -like "*用户名已存在*") {
Write-Host "✅ PASS: Correct error message for existing user" -ForegroundColor Green
} else {
Write-Host "❌ FAIL: Wrong error message for existing user" -ForegroundColor Red
}
}
Write-Host "`nTest completed!" -ForegroundColor Green
# Test 4: Get verification code and register with email
Write-Host "`n📋 Get verification code and register with email" -ForegroundColor Yellow
try {
$emailResponse = Invoke-RestMethod -Uri "$baseUrl/auth/send-email-verification" -Method POST -Body (@{email = "newuser@test.com"} | ConvertTo-Json) -ContentType "application/json"
if ($emailResponse.data.verification_code) {
$verificationCode = $emailResponse.data.verification_code
Write-Host "Got verification code: $verificationCode" -ForegroundColor Green
$result4 = Test-ApiCall -TestName "Register with valid email and verification code" -Url "$baseUrl/auth/register" -Body (@{
username = "emailuser_$(Get-Random)"
password = "password123"
nickname = "Email User"
email = "newuser@test.com"
email_verification_code = $verificationCode
} | ConvertTo-Json)
if ($result4 -and $result4.success) {
Write-Host "✅ PASS: Email registration successful" -ForegroundColor Green
}
}
} catch {
Write-Host "⚠️ Could not test email verification (email service may not be configured)" -ForegroundColor Yellow
}
Write-Host "`n🎯 Test Summary" -ForegroundColor Green
Write-Host "===============" -ForegroundColor Green
Write-Host "✅ Registration logic has been fixed:" -ForegroundColor White
Write-Host " • User existence checked BEFORE verification code validation" -ForegroundColor White
Write-Host " • Proper error messages for different scenarios" -ForegroundColor White
Write-Host " • Verification codes not wasted on existing users" -ForegroundColor White