forked from baron/baron-sso
- Added support for fixed UUIDs during bulk registration (Search-first + ExternalID mapping) - Implemented idempotency and visibility restoration for soft-deleted users - Enhanced bulk upload UI to show 'New/Updated/Unchanged' status and modified fields - Added logic to reclaim identifiers (login_id) from colliding records - Added frontend E2E and backend unit tests for UUID integrity and conflict handling - Fixed i18n, formatting, and mock tests to satisfy code-check - Applied 'go fix' for 'omitzero' tags and general Go standards
111 lines
3.1 KiB
Go
111 lines
3.1 KiB
Go
package handler
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestHandleKratosCourierRelay_Email(t *testing.T) {
|
|
redis := &mockRedisRepo{data: make(map[string]string)}
|
|
emailSvc := &mockEmailService{}
|
|
|
|
h := &AuthHandler{
|
|
RedisService: redis,
|
|
EmailService: emailSvc,
|
|
}
|
|
app := fiber.New()
|
|
app.Post("/api/v1/auth/kratos/courier", h.HandleKratosCourierRelay)
|
|
|
|
// Simulate Kratos Courier Request for Email
|
|
reqBody := map[string]any{
|
|
"recipient": "user@example.com",
|
|
"template_type": "verification_code",
|
|
"template_data": map[string]any{
|
|
"verification_code": "123456",
|
|
},
|
|
"subject": "Verify your email",
|
|
"body": "Your code is 123456",
|
|
}
|
|
body, _ := json.Marshal(reqBody)
|
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/auth/kratos/courier", bytes.NewReader(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, _ := app.Test(req, -1)
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
}
|
|
|
|
func TestVerifySignupCode_Success(t *testing.T) {
|
|
redis := &mockRedisRepo{data: make(map[string]string)}
|
|
h := &AuthHandler{
|
|
RedisService: redis,
|
|
}
|
|
app := fiber.New()
|
|
app.Post("/api/v1/auth/signup/verify", h.VerifySignupCode)
|
|
|
|
// Mock stored code in redis
|
|
// signup:email:user@test.com -> {"code":"654321", "verified":false, "expires_at":...}
|
|
state := map[string]any{
|
|
"code": "654321",
|
|
"verified": false,
|
|
"expires_at": 9999999999, // far future
|
|
}
|
|
stateJSON, _ := json.Marshal(state)
|
|
redis.data["signup:email:user@test.com"] = string(stateJSON)
|
|
|
|
// Verify Code
|
|
verifyBody := map[string]string{
|
|
"type": "email",
|
|
"target": "user@test.com",
|
|
"code": "654321",
|
|
}
|
|
body, _ := json.Marshal(verifyBody)
|
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/auth/signup/verify", bytes.NewReader(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, _ := app.Test(req, -1)
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
|
|
var res map[string]any
|
|
json.NewDecoder(resp.Body).Decode(&res)
|
|
assert.True(t, res["success"].(bool))
|
|
|
|
// Check redis state updated to verified
|
|
val, _ := redis.Get("signup:email:user@test.com")
|
|
var updatedState map[string]any
|
|
json.Unmarshal([]byte(val), &updatedState)
|
|
assert.True(t, updatedState["verified"].(bool))
|
|
}
|
|
|
|
func TestVerifySignupCode_Invalid(t *testing.T) {
|
|
redis := &mockRedisRepo{data: make(map[string]string)}
|
|
h := &AuthHandler{
|
|
RedisService: redis,
|
|
}
|
|
app := fiber.New()
|
|
app.Post("/api/v1/auth/signup/verify", h.VerifySignupCode)
|
|
|
|
stateJSON, _ := json.Marshal(map[string]any{
|
|
"code": "111111",
|
|
"expires_at": 9999999999,
|
|
})
|
|
redis.data["signup:email:user@test.com"] = string(stateJSON)
|
|
|
|
verifyBody := map[string]string{
|
|
"type": "email",
|
|
"target": "user@test.com",
|
|
"code": "222222", // wrong code
|
|
}
|
|
body, _ := json.Marshal(verifyBody)
|
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/auth/signup/verify", bytes.NewReader(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, _ := app.Test(req, -1)
|
|
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
|
}
|