첫 커밋: 로컬 프로젝트 업로드
This commit is contained in:
144
baron-sso/backend/internal/handler/auth_handler_signup_test.go
Normal file
144
baron-sso/backend/internal/handler/auth_handler_signup_test.go
Normal file
@@ -0,0 +1,144 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"baron-sso-backend/internal/domain"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// --- Local Mocks for Signup Test ---
|
||||
|
||||
type MockRedisForSignup struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (m *MockRedisForSignup) Set(key string, value string, ttl time.Duration) error {
|
||||
return m.Called(key, value, ttl).Error(0)
|
||||
}
|
||||
|
||||
func (m *MockRedisForSignup) Get(key string) (string, error) {
|
||||
args := m.Called(key)
|
||||
return args.String(0), args.Error(1)
|
||||
}
|
||||
|
||||
func (m *MockRedisForSignup) Delete(key string) error {
|
||||
return m.Called(key).Error(0)
|
||||
}
|
||||
func (m *MockRedisForSignup) StoreVerificationCode(phone, code string) error { return nil }
|
||||
func (m *MockRedisForSignup) GetVerificationCode(phone string) (string, error) { return "", nil }
|
||||
func (m *MockRedisForSignup) DeleteVerificationCode(phone string) error { return nil }
|
||||
func (m *MockRedisForSignup) Ping(ctx context.Context) error { return nil }
|
||||
|
||||
type MockIdpForSignup struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (m *MockIdpForSignup) Name() string { return "mock-idp" }
|
||||
func (m *MockIdpForSignup) GetMetadata() (*domain.IDPMetadata, error) {
|
||||
return &domain.IDPMetadata{SupportedFields: []string{"email", "name", "phoneNumber", "grade", "department"}}, nil
|
||||
}
|
||||
|
||||
func (m *MockIdpForSignup) CreateUser(user *domain.BrokerUser, password string) (string, error) {
|
||||
args := m.Called(user, password)
|
||||
return args.String(0), args.Error(1)
|
||||
}
|
||||
|
||||
func (m *MockIdpForSignup) SignIn(loginID, password string) (*domain.AuthInfo, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *MockIdpForSignup) UserExists(loginID string) (bool, error) { return false, nil }
|
||||
func (m *MockIdpForSignup) IssueSession(loginID string) (*domain.AuthInfo, error) { return nil, nil }
|
||||
func (m *MockIdpForSignup) InitiateLinkLogin(loginID, returnTo string) (*domain.LinkLoginInit, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockIdpForSignup) VerifyLoginCode(loginID, flowID, code string) (*domain.AuthInfo, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockIdpForSignup) GetPasswordPolicy() (*domain.PasswordPolicy, error) {
|
||||
return &domain.PasswordPolicy{MinLength: 12}, nil
|
||||
}
|
||||
func (m *MockIdpForSignup) InitiatePasswordReset(loginID, redirectUrl string) error { return nil }
|
||||
func (m *MockIdpForSignup) VerifyPasswordResetToken(token string) (*domain.AuthInfo, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockIdpForSignup) UpdateUserPassword(loginID, newPassword string, r *http.Request) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestSignup_TenantSlugValidation(t *testing.T) {
|
||||
app := fiber.New()
|
||||
mockTenantSvc := new(MockTenantService)
|
||||
mockRedis := new(MockRedisForSignup)
|
||||
mockIdp := new(MockIdpForSignup)
|
||||
|
||||
h := &AuthHandler{
|
||||
TenantService: mockTenantSvc,
|
||||
RedisService: mockRedis,
|
||||
IdpProvider: mockIdp,
|
||||
}
|
||||
|
||||
app.Post("/signup", h.Signup)
|
||||
|
||||
// Prepare mock state (already verified email/phone)
|
||||
verifiedState, _ := json.Marshal(map[string]any{
|
||||
"verified": true,
|
||||
"expires_at": time.Now().Add(time.Hour).Unix(),
|
||||
})
|
||||
mockRedis.On("Get", mock.Anything).Return(string(verifiedState), nil)
|
||||
|
||||
t.Run("Rejects legacy CompanyCode", func(t *testing.T) {
|
||||
reqBody := domain.SignupRequest{
|
||||
Email: "user@gmail.com",
|
||||
Password: "StrongPass123!",
|
||||
Name: "Test User",
|
||||
Phone: "010-1234-5678",
|
||||
TermsAccepted: true,
|
||||
CompanyCode: "new-slug",
|
||||
}
|
||||
body, _ := json.Marshal(reqBody)
|
||||
|
||||
req := httptest.NewRequest("POST", "/signup", bytes.NewReader(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
resp, _ := app.Test(req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("Active Tenant Slug", func(t *testing.T) {
|
||||
reqBody := domain.SignupRequest{
|
||||
Email: "user@hanmaceng.co.kr",
|
||||
Password: "StrongPass123!",
|
||||
Name: "Test User",
|
||||
Phone: "010-1234-5678",
|
||||
TermsAccepted: true,
|
||||
TenantSlug: "hanmac",
|
||||
}
|
||||
body, _ := json.Marshal(reqBody)
|
||||
|
||||
validTenant := &domain.Tenant{ID: "t1", Slug: "hanmac", Status: domain.TenantStatusActive}
|
||||
mockTenantSvc.On("GetTenantByDomain", mock.Anything, "hanmaceng.co.kr").Return(&domain.Tenant{Slug: "hanmac"}, nil).Once()
|
||||
mockTenantSvc.On("ProvisionTenantByDomain", mock.Anything, "hanmaceng.co.kr").Return(validTenant, nil).Maybe()
|
||||
mockTenantSvc.On("GetTenantBySlug", mock.Anything, "hanmac").Return(validTenant, nil).Once()
|
||||
mockTenantSvc.On("GetTenant", mock.Anything, "t1").Return(validTenant, nil).Once()
|
||||
mockIdp.On("CreateUser", mock.Anything, mock.Anything).Return("user-id", nil).Once()
|
||||
mockRedis.On("Delete", mock.Anything).Return(nil)
|
||||
|
||||
req := httptest.NewRequest("POST", "/signup", bytes.NewReader(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
resp, _ := app.Test(req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user