backend/pkg/permission/domain/entity/token_test.go

319 lines
6.2 KiB
Go

package entity
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestToken_IsExpired(t *testing.T) {
tests := []struct {
name string
token *Token
expected bool
}{
{
name: "expired token",
token: &Token{
ID: "test-id",
UID: "test-uid",
ExpiresIn: int(time.Now().Add(-time.Hour).Unix()),
},
expected: true,
},
{
name: "valid token",
token: &Token{
ID: "test-id",
UID: "test-uid",
ExpiresIn: int(time.Now().Add(time.Hour).Unix()),
},
expected: false,
},
{
name: "token expiring now",
token: &Token{
ID: "test-id",
UID: "test-uid",
ExpiresIn: int(time.Now().Unix()) - 1,
},
expected: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := tt.token.IsExpired()
assert.Equal(t, tt.expected, result)
})
}
}
func TestToken_IsRefreshExpired(t *testing.T) {
tests := []struct {
name string
token *Token
expected bool
}{
{
name: "expired refresh token",
token: &Token{
ID: "test-id",
UID: "test-uid",
RefreshExpiresIn: int(time.Now().Add(-time.Hour).Unix()),
},
expected: true,
},
{
name: "valid refresh token",
token: &Token{
ID: "test-id",
UID: "test-uid",
RefreshExpiresIn: int(time.Now().Add(time.Hour).Unix()),
},
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := tt.token.IsRefreshExpired()
assert.Equal(t, tt.expected, result)
})
}
}
func TestToken_RedisRefreshExpiredSec(t *testing.T) {
tests := []struct {
name string
token *Token
expected int
}{
{
name: "token with future expiry",
token: &Token{
ID: "test-id",
UID: "test-uid",
RefreshExpiresIn: int(time.Now().Add(time.Hour).Unix()),
},
expected: 3600, // Approximately 1 hour in seconds
},
{
name: "token already expired",
token: &Token{
ID: "test-id",
UID: "test-uid",
RefreshExpiresIn: int(time.Now().Add(-time.Hour).Unix()),
},
expected: 0,
},
{
name: "token expiring now",
token: &Token{
ID: "test-id",
UID: "test-uid",
RefreshExpiresIn: int(time.Now().Unix()),
},
expected: 0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := tt.token.RedisRefreshExpiredSec()
if tt.expected == 0 {
assert.Equal(t, 0, result)
} else {
// Allow some margin for test execution time
assert.InDelta(t, tt.expected, result, 5)
}
})
}
}
func TestToken_Validate(t *testing.T) {
tests := []struct {
name string
token *Token
wantErr bool
expectedErr error
}{
{
name: "valid token",
token: &Token{
ID: "test-id",
UID: "test-uid",
AccessToken: "test-access-token",
ExpiresIn: int(time.Now().Add(time.Hour).Unix()),
},
wantErr: false,
},
{
name: "missing ID",
token: &Token{
ID: "",
UID: "test-uid",
AccessToken: "test-access-token",
},
wantErr: true,
expectedErr: ErrInvalidTokenID,
},
{
name: "missing UID",
token: &Token{
ID: "test-id",
UID: "",
AccessToken: "test-access-token",
},
wantErr: true,
expectedErr: ErrInvalidUID,
},
{
name: "missing AccessToken",
token: &Token{
ID: "test-id",
UID: "test-uid",
AccessToken: "",
},
wantErr: true,
expectedErr: ErrInvalidAccessToken,
},
{
name: "all fields missing",
token: &Token{
ID: "",
UID: "",
AccessToken: "",
},
wantErr: true,
expectedErr: ErrInvalidTokenID,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.token.Validate()
if tt.wantErr {
assert.Error(t, err)
if tt.expectedErr != nil {
assert.Equal(t, tt.expectedErr, err)
}
} else {
assert.NoError(t, err)
}
})
}
}
func TestTicket(t *testing.T) {
t.Run("ticket with data", func(t *testing.T) {
ticket := Ticket{
Data: map[string]string{
"uid": "user123",
"role": "admin",
},
Token: Token{
ID: "token123",
UID: "user123",
AccessToken: "access-token",
},
}
assert.NotNil(t, ticket.Data)
assert.Equal(t, "user123", ticket.Data["uid"])
assert.Equal(t, "admin", ticket.Data["role"])
assert.Equal(t, "token123", ticket.Token.ID)
})
t.Run("empty ticket", func(t *testing.T) {
ticket := Ticket{}
assert.Nil(t, ticket.Data)
assert.Empty(t, ticket.Token.ID)
})
}
func TestToken_DeviceID(t *testing.T) {
tests := []struct {
name string
deviceID string
}{
{
name: "with device ID",
deviceID: "device123",
},
{
name: "empty device ID",
deviceID: "",
},
{
name: "UUID device ID",
deviceID: "550e8400-e29b-41d4-a716-446655440000",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
token := &Token{
ID: "test-id",
UID: "test-uid",
DeviceID: tt.deviceID,
AccessToken: "test-token",
}
assert.Equal(t, tt.deviceID, token.DeviceID)
})
}
}
func TestToken_RefreshToken(t *testing.T) {
tests := []struct {
name string
refreshToken string
}{
{
name: "with refresh token",
refreshToken: "refresh-token-123",
},
{
name: "empty refresh token",
refreshToken: "",
},
{
name: "long refresh token",
refreshToken: "very-long-refresh-token-with-hash-abcdef1234567890",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
token := &Token{
ID: "test-id",
UID: "test-uid",
AccessToken: "access-token",
RefreshToken: tt.refreshToken,
}
assert.Equal(t, tt.refreshToken, token.RefreshToken)
})
}
}
func TestToken_Timestamps(t *testing.T) {
now := time.Now()
token := &Token{
ID: "test-id",
UID: "test-uid",
AccessToken: "access-token",
AccessCreateAt: now,
RefreshCreateAt: now.Add(time.Second),
}
assert.Equal(t, now, token.AccessCreateAt)
assert.True(t, token.RefreshCreateAt.After(token.AccessCreateAt))
}