You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
4.5 KiB
Go

package auth
import (
"testing"
"github.com/gofiber/fiber/v2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/valyala/fasthttp"
)
// setupTestContext creates a proper fiber context for testing
func setupTestContext(app *fiber.App) *fiber.Ctx {
reqCtx := &fasthttp.RequestCtx{}
reqCtx.Request.SetBody([]byte(""))
reqCtx.Request.Header.SetMethod(fiber.MethodGet)
reqCtx.Request.SetRequestURI("/")
c := app.AcquireCtx(reqCtx)
return c
}
func TestGetUserFromContext(t *testing.T) {
app := fiber.New()
t.Run("Successfully extracts user context", func(t *testing.T) {
c := setupTestContext(app)
defer app.ReleaseCtx(c)
// Set user context
c.Locals(UserIDKey, "user123")
c.Locals(UsernameKey, "testuser")
c.Locals(EmailKey, "test@example.com")
c.Locals(RolesKey, []string{"player", "admin"})
user, err := GetUserFromContext(c)
require.NoError(t, err)
assert.Equal(t, "user123", user.UserID)
assert.Equal(t, "testuser", user.Username)
assert.Equal(t, "test@example.com", user.Email)
assert.Equal(t, []string{"player", "admin"}, user.Roles)
})
t.Run("Returns error when user not authenticated", func(t *testing.T) {
c := setupTestContext(app)
defer app.ReleaseCtx(c)
user, err := GetUserFromContext(c)
require.Error(t, err)
assert.Nil(t, user)
assert.Contains(t, err.Error(), ErrUserNotAuthenticated)
})
t.Run("Handles missing optional fields gracefully", func(t *testing.T) {
c := setupTestContext(app)
defer app.ReleaseCtx(c)
// Only set required user_id
c.Locals(UserIDKey, "user123")
user, err := GetUserFromContext(c)
require.NoError(t, err)
assert.Equal(t, "user123", user.UserID)
assert.Equal(t, "", user.Username)
assert.Equal(t, "", user.Email)
assert.Nil(t, user.Roles)
})
}
func TestIsAuthenticated(t *testing.T) {
app := fiber.New()
t.Run("Returns true when user is authenticated", func(t *testing.T) {
c := setupTestContext(app)
defer app.ReleaseCtx(c)
c.Locals(UserIDKey, "user123")
assert.True(t, IsAuthenticated(c))
})
t.Run("Returns false when user is not authenticated", func(t *testing.T) {
c := setupTestContext(app)
defer app.ReleaseCtx(c)
assert.False(t, IsAuthenticated(c))
})
}
func TestHasRole(t *testing.T) {
app := fiber.New()
t.Run("Returns true when user has the role", func(t *testing.T) {
c := setupTestContext(app)
defer app.ReleaseCtx(c)
c.Locals(RolesKey, []string{"player", "admin"})
assert.True(t, HasRole(c, "admin"))
assert.True(t, HasRole(c, "player"))
})
t.Run("Returns false when user doesn't have the role", func(t *testing.T) {
c := setupTestContext(app)
defer app.ReleaseCtx(c)
c.Locals(RolesKey, []string{"player"})
assert.False(t, HasRole(c, "admin"))
})
t.Run("Returns false when no roles are set", func(t *testing.T) {
c := setupTestContext(app)
defer app.ReleaseCtx(c)
assert.False(t, HasRole(c, "admin"))
})
t.Run("Returns false when roles is not a string slice", func(t *testing.T) {
c := setupTestContext(app)
defer app.ReleaseCtx(c)
c.Locals(RolesKey, "not-a-slice")
assert.False(t, HasRole(c, "admin"))
})
}
func TestHasAnyRole(t *testing.T) {
app := fiber.New()
t.Run("Returns true when user has any of the roles", func(t *testing.T) {
c := setupTestContext(app)
defer app.ReleaseCtx(c)
c.Locals(RolesKey, []string{"player"})
assert.True(t, HasAnyRole(c, "admin", "player"))
assert.True(t, HasAnyRole(c, "player"))
})
t.Run("Returns false when user doesn't have any of the roles", func(t *testing.T) {
c := setupTestContext(app)
defer app.ReleaseCtx(c)
c.Locals(RolesKey, []string{"player"})
assert.False(t, HasAnyRole(c, "admin", "moderator"))
})
t.Run("Returns false when no roles are set", func(t *testing.T) {
c := setupTestContext(app)
defer app.ReleaseCtx(c)
assert.False(t, HasAnyRole(c, "admin", "player"))
})
t.Run("Returns false when roles is not a string slice", func(t *testing.T) {
c := setupTestContext(app)
defer app.ReleaseCtx(c)
c.Locals(RolesKey, 123)
assert.False(t, HasAnyRole(c, "admin"))
})
}
func TestIsAdmin(t *testing.T) {
app := fiber.New()
t.Run("Returns true when user has admin role", func(t *testing.T) {
c := setupTestContext(app)
defer app.ReleaseCtx(c)
c.Locals(RolesKey, []string{"admin", "player"})
assert.True(t, IsAdmin(c))
})
t.Run("Returns false when user doesn't have admin role", func(t *testing.T) {
c := setupTestContext(app)
defer app.ReleaseCtx(c)
c.Locals(RolesKey, []string{"player"})
assert.False(t, IsAdmin(c))
})
}