Files
techxcar/backend/internal/auth/handler_test.go
T
Luciano Milani 5de37bb512 Inicial
2026-07-02 12:47:55 +01:00

153 lines
4.8 KiB
Go

package auth_test
import (
"bytes"
"context"
"encoding/json"
"net/http/httptest"
"testing"
"time"
"github.com/gofiber/fiber/v2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/techxcar/backend/internal/auth"
"github.com/techxcar/backend/internal/config"
)
// stubRepo is a minimal in-memory stub for testing auth handlers without a real DB.
type stubRepo struct {
superAdmins map[string]*auth.LoginSuperAdmin
tenants map[string]*auth.LoginTenant
users map[string]*auth.LoginUser
}
func (s *stubRepo) GetSuperAdminByEmail(_ context.Context, email string) (*auth.LoginSuperAdmin, error) {
a, _ := s.superAdmins[email]
return a, nil
}
func (s *stubRepo) GetTenantBySlug(_ context.Context, slug string) (*auth.LoginTenant, error) {
t, _ := s.tenants[slug]
return t, nil
}
func (s *stubRepo) GetTenantUserByEmail(_ context.Context, tenantID, email string) (*auth.LoginUser, error) {
key := tenantID + ":" + email
u, _ := s.users[key]
return u, nil
}
func newTestApp(repo auth.LoginRepository, cfg *config.Config) *fiber.App {
app := fiber.New(fiber.Config{ErrorHandler: func(c *fiber.Ctx, err error) error {
code := fiber.StatusInternalServerError
if e, ok := err.(*fiber.Error); ok {
code = e.Code
}
return c.Status(code).JSON(fiber.Map{"data": nil, "error": err.Error()})
}})
app.Post("/api/v1/auth/login", auth.LoginHandler(repo, nil, cfg))
app.Post("/api/v1/auth/refresh", auth.RefreshHandler(nil, cfg))
app.Post("/api/v1/auth/logout", auth.LogoutHandler(nil))
return app
}
func TestLogin_superAdmin_success(t *testing.T) {
hash, _ := auth.HashPassword("secret123")
repo := &stubRepo{
superAdmins: map[string]*auth.LoginSuperAdmin{
"admin@example.com": {ID: "sa-1", Email: "admin@example.com", PasswordHash: hash},
},
}
cfg := &config.Config{JWTSecret: testSecret}
app := newTestApp(repo, cfg)
body, _ := json.Marshal(map[string]string{"email": "admin@example.com", "password": "secret123"})
req := httptest.NewRequest("POST", "/api/v1/auth/login", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
resp, err := app.Test(req)
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
var result map[string]any
require.NoError(t, json.NewDecoder(resp.Body).Decode(&result))
data := result["data"].(map[string]any)
assert.NotEmpty(t, data["access_token"])
assert.NotNil(t, data["user"])
}
func TestLogin_wrongPassword(t *testing.T) {
hash, _ := auth.HashPassword("secret123")
repo := &stubRepo{
superAdmins: map[string]*auth.LoginSuperAdmin{
"admin@example.com": {ID: "sa-1", Email: "admin@example.com", PasswordHash: hash},
},
}
cfg := &config.Config{JWTSecret: testSecret}
app := newTestApp(repo, cfg)
body, _ := json.Marshal(map[string]string{"email": "admin@example.com", "password": "wrongpass"})
req := httptest.NewRequest("POST", "/api/v1/auth/login", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
resp, err := app.Test(req)
require.NoError(t, err)
assert.Equal(t, 401, resp.StatusCode)
}
func TestLogin_tenantUser_success(t *testing.T) {
hash, _ := auth.HashPassword("tenantpass")
repo := &stubRepo{
tenants: map[string]*auth.LoginTenant{
"my-workshop": {ID: "11111111-1111-1111-1111-111111111111", Status: "active"},
},
users: map[string]*auth.LoginUser{
"11111111-1111-1111-1111-111111111111:user@workshop.com": {
ID: "u-1", Email: "user@workshop.com", PasswordHash: hash,
Role: "tenant_admin", Name: "User", Active: true,
},
},
}
cfg := &config.Config{JWTSecret: testSecret}
app := newTestApp(repo, cfg)
body, _ := json.Marshal(map[string]string{
"email": "user@workshop.com", "password": "tenantpass", "tenant_slug": "my-workshop",
})
req := httptest.NewRequest("POST", "/api/v1/auth/login", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
resp, err := app.Test(req)
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
var result map[string]any
require.NoError(t, json.NewDecoder(resp.Body).Decode(&result))
data := result["data"].(map[string]any)
token := data["access_token"].(string)
claims, err := auth.ValidateToken(token, testSecret)
require.NoError(t, err)
assert.Equal(t, "11111111-1111-1111-1111-111111111111", claims.TenantID)
assert.Equal(t, "tenant_admin", claims.Role)
_ = time.Now()
}
func TestLogin_unknownTenant(t *testing.T) {
repo := &stubRepo{tenants: map[string]*auth.LoginTenant{}}
cfg := &config.Config{JWTSecret: testSecret}
app := newTestApp(repo, cfg)
body, _ := json.Marshal(map[string]string{
"email": "user@workshop.com", "password": "pass", "tenant_slug": "nonexistent",
})
req := httptest.NewRequest("POST", "/api/v1/auth/login", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
resp, err := app.Test(req)
require.NoError(t, err)
assert.Equal(t, 401, resp.StatusCode)
}