app-cloudep-permission-server/pkg/domain/entity/token_test.go

164 lines
5.1 KiB
Go
Raw Normal View History

2025-02-12 01:51:46 +00:00
package entity
import (
"testing"
"time"
)
// TestAccessTokenExpires 測試 AccessTokenExpires 方法是否能正確將 ExpiresIn 轉換成 time.Duration
func TestAccessTokenExpires(t *testing.T) {
tests := []struct {
name string // 測試案例名稱
expiresIn int64 // 輸入的 ExpiresIn 值,單位為秒
want time.Duration // 預期返回的時間間隔
}{
{"zero expiration", 0, 0},
{"1 second expiration", 1, 1 * time.Second},
{"60 seconds expiration", 60, 60 * time.Second},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// 建立一個 Token 實例,僅設置 ExpiresIn 欄位
token := Token{
ExpiresIn: tt.expiresIn,
}
// 呼叫 AccessTokenExpires 方法
got := token.AccessTokenExpires() // ex 1m0s, 1s, 0s etc ....
// 檢查返回值是否與預期相符
if got != tt.want {
t.Errorf("AccessTokenExpires() = %v, want %v", got, tt.want)
}
})
}
}
// TestRefreshTokenExpires 測試 RefreshTokenExpires 方法是否能正確將 RefreshExpiresIn轉換成 time.Duration
func TestRefreshTokenExpires(t *testing.T) {
tests := []struct {
name string
refreshExpiresIn int64
want time.Duration
}{
{"zero", 0, 0},
{"1 second", 1, 1 * time.Second},
{"60 seconds", 60, 60 * time.Second},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
token := Token{
RefreshExpiresIn: tt.refreshExpiresIn,
}
got := token.RefreshTokenExpires()
if got != tt.want {
t.Errorf("RefreshTokenExpires() = %v, want %v", got, tt.want)
}
})
}
}
// TestRefreshTokenExpiresUnix 測試 RefreshTokenExpiresUnix 方法返回的 UnixNano 時間戳是否大致符合預期
func TestRefreshTokenExpiresUnix(t *testing.T) {
// 設定 refreshExpiresIn 為 60 秒
token := Token{
RefreshExpiresIn: 60,
}
// 取得測試開始時的時間
now := time.Now()
// 預期值now + 60 秒
expected := now.Add(60 * time.Second).UnixNano()
got := token.RefreshTokenExpiresUnix()
// 設定允許誤差 50 毫秒
tolerance := int64(50 * time.Millisecond)
if got < expected-tolerance || got > expected+tolerance {
t.Errorf("RefreshTokenExpiresUnix() = %v, want approx %v", got, expected)
}
}
// TestIsExpires 測試 IsExpires 方法判斷 token 是否過期
func TestIsExpires(t *testing.T) {
now := time.Now()
// 測試未過期token 創建時間為現在,過期時長為 10 秒
tokenValid := Token{
AccessCreateAt: now.UnixNano(),
ExpiresIn: 10, // 此處 ExpiresIn 為有效時長(秒)
}
if tokenValid.IsExpires() {
t.Errorf("IsExpires() 返回 true但 token 尚未過期")
}
// 測試已過期token 創建時間為 20 秒前,過期時長為 10 秒
tokenExpired := Token{
AccessCreateAt: now.Add(-20 * time.Second).UnixNano(),
ExpiresIn: 10,
}
if !tokenExpired.IsExpires() {
t.Errorf("IsExpires() 返回 false但 token 已過期")
}
}
// TestRedisExpiredSec 測試 RedisExpiredSec 方法
// 此方法根據 t.ExpiresIn (UnixNano 表示的到期時間) 與當前 UTC 時間計算剩餘秒數
func TestRedisExpiredSec(t *testing.T) {
// 定義測試案例:
// - expireOffset 為從當前時間的偏移量(正數表示未過期,負數表示已過期)
// - minExpected 與 maxExpected 為允許的返回值範圍(因為執行期間會有少量延遲)
tests := []struct {
name string
expireOffset time.Duration // token 過期時間相對於當前的偏移量
minExpected int64 // 預期返回值下限(秒)
maxExpected int64 // 預期返回值上限(秒)
}{
{"Not expired +10s", 10 * time.Second, 9, 10},
{"Expired -5s", -5 * time.Second, -6, -5},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
now := time.Now().UTC()
// token 的到期時間設定為當前時間加上偏移量
expTime := now.Add(tt.expireOffset)
token := Token{
ExpiresIn: expTime.UnixNano(),
}
got := token.RedisExpiredSec()
if got < tt.minExpected || got > tt.maxExpected {
t.Errorf("RedisExpiredSec() = %d, want between %d and %d", got, tt.minExpected, tt.maxExpected)
}
})
}
}
// TestRedisRefreshExpiredSec 測試 RedisRefreshExpiredSec 方法
// 此方法根據 t.RefreshExpiresIn (UnixNano 表示的刷新到期時間) 與當前 UTC 時間計算剩餘秒數
func TestRedisRefreshExpiredSec(t *testing.T) {
tests := []struct {
name string
expireOffset time.Duration // 刷新 token 到期時間相對於當前的偏移量
minExpected int64 // 預期返回值下限(秒)
maxExpected int64 // 預期返回值上限(秒)
}{
{"Not expired +20s", 20 * time.Second, 19, 20},
{"Expired -5s", -5 * time.Second, -6, -5},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
now := time.Now().UTC()
expTime := now.Add(tt.expireOffset)
token := Token{
RefreshExpiresIn: expTime.UnixNano(),
}
got := token.RedisRefreshExpiredSec()
if got < tt.minExpected || got > tt.maxExpected {
t.Errorf("RedisRefreshExpiredSec() = %d, want between %d and %d", got, tt.minExpected, tt.maxExpected)
}
})
}
}