Inicial
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
package tenant_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"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"
|
||||
"github.com/techxcar/backend/internal/tenant"
|
||||
)
|
||||
|
||||
const handlerTestSecret = "test-secret-32-chars-minimum-ok!"
|
||||
|
||||
func buildAdminApp(repo *tenant.Repository, 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()})
|
||||
}})
|
||||
tenant.RegisterRoutes(app, repo, nil, cfg)
|
||||
return app
|
||||
}
|
||||
|
||||
func adminToken(t *testing.T, secret string) string {
|
||||
t.Helper()
|
||||
tok, err := auth.GenerateAccessToken("sa-1", "", "super_admin", secret)
|
||||
require.NoError(t, err)
|
||||
return tok
|
||||
}
|
||||
|
||||
func TestListTenants_requiresAuth(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
repo := tenant.NewRepository(db)
|
||||
cfg := &config.Config{JWTSecret: handlerTestSecret}
|
||||
app := buildAdminApp(repo, cfg)
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/v1/admin/tenants", nil)
|
||||
resp, err := app.Test(req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 401, resp.StatusCode)
|
||||
}
|
||||
|
||||
func TestListTenants_success(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
repo := tenant.NewRepository(db)
|
||||
cfg := &config.Config{JWTSecret: handlerTestSecret}
|
||||
app := buildAdminApp(repo, cfg)
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/v1/admin/tenants", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+adminToken(t, handlerTestSecret))
|
||||
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))
|
||||
assert.Nil(t, result["error"])
|
||||
}
|
||||
|
||||
func TestTenantAccessHandler(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
repo := tenant.NewRepository(db)
|
||||
cfg := &config.Config{JWTSecret: handlerTestSecret}
|
||||
app := buildAdminApp(repo, cfg)
|
||||
|
||||
ctx := t.Context()
|
||||
slug := "access-test-" + t.Name()
|
||||
ten, err := repo.CreateTenant(ctx, slug, "Tenant Access Test")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
db.Pool.Exec(ctx, "DELETE FROM tenants WHERE id = $1", ten.ID)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/v1/admin/tenants/"+ten.ID+"/access", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+adminToken(t, handlerTestSecret))
|
||||
resp, err := app.Test(req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 200, resp.StatusCode)
|
||||
|
||||
var body struct {
|
||||
Data struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
Tenant struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Slug string `json:"slug"`
|
||||
} `json:"tenant"`
|
||||
} `json:"data"`
|
||||
Error *string `json:"error"`
|
||||
}
|
||||
require.NoError(t, json.NewDecoder(resp.Body).Decode(&body))
|
||||
assert.Nil(t, body.Error)
|
||||
assert.NotEmpty(t, body.Data.AccessToken)
|
||||
assert.Equal(t, ten.ID, body.Data.Tenant.ID)
|
||||
assert.Equal(t, "Tenant Access Test", body.Data.Tenant.Name)
|
||||
assert.Equal(t, slug, body.Data.Tenant.Slug)
|
||||
|
||||
claims, err := auth.ValidateToken(body.Data.AccessToken, handlerTestSecret)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "sa-1", claims.UserID)
|
||||
assert.Equal(t, ten.ID, claims.TenantID)
|
||||
assert.Equal(t, "tenant_admin", claims.Role)
|
||||
}
|
||||
|
||||
func TestTenantAccessHandler_notFound(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
repo := tenant.NewRepository(db)
|
||||
cfg := &config.Config{JWTSecret: handlerTestSecret}
|
||||
app := buildAdminApp(repo, cfg)
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/v1/admin/tenants/nonexistent-id/access", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+adminToken(t, handlerTestSecret))
|
||||
resp, err := app.Test(req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 404, resp.StatusCode)
|
||||
}
|
||||
|
||||
func TestTenantAccessHandler_inactive(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
repo := tenant.NewRepository(db)
|
||||
cfg := &config.Config{JWTSecret: handlerTestSecret}
|
||||
app := buildAdminApp(repo, cfg)
|
||||
|
||||
ctx := t.Context()
|
||||
slug := "inactive-test-" + t.Name()
|
||||
ten, err := repo.CreateTenant(ctx, slug, "Tenant Inactive Test")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
db.Pool.Exec(ctx, "DELETE FROM tenants WHERE id = $1", ten.ID)
|
||||
})
|
||||
|
||||
// Update tenant status to something other than "active"
|
||||
_, err = db.Pool.Exec(ctx, "UPDATE public.tenants SET status = 'suspended' WHERE id = $1", ten.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/v1/admin/tenants/"+ten.ID+"/access", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+adminToken(t, handlerTestSecret))
|
||||
resp, err := app.Test(req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 404, resp.StatusCode)
|
||||
}
|
||||
|
||||
func TestGetInvite_notFound(t *testing.T) {
|
||||
db := setupDB(t)
|
||||
repo := tenant.NewRepository(db)
|
||||
cfg := &config.Config{JWTSecret: handlerTestSecret}
|
||||
app := buildAdminApp(repo, cfg)
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/v1/invites/nonexistent-token", nil)
|
||||
resp, err := app.Test(req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 404, resp.StatusCode)
|
||||
}
|
||||
Reference in New Issue
Block a user